@pallasoft/ps-table-components 1.28.4 → 1.29.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.js +2 -4
- package/dist/components/ps-report-table-skeleton.d.ts +10 -0
- package/dist/components/ps-report-table-skeleton.js +29 -0
- package/dist/components/ps-report-table.d.ts +28 -0
- package/dist/components/ps-report-table.js +45 -0
- package/dist/constants/ps-report-column-align.d.ts +6 -0
- package/dist/constants/ps-report-column-align.js +8 -0
- package/dist/constants/ps-report-row-kind.d.ts +7 -0
- package/dist/constants/ps-report-row-kind.js +9 -0
- package/dist/constants/ps-report-row-tone.d.ts +7 -0
- package/dist/constants/ps-report-row-tone.js +9 -0
- package/dist/constants/ps-report-table-classes.d.ts +52 -0
- package/dist/constants/ps-report-table-classes.js +59 -0
- package/dist/constants/ps-report-table-config.d.ts +9 -0
- package/dist/constants/ps-report-table-config.js +9 -0
- package/dist/constants/ps-report-table-density.d.ts +5 -0
- package/dist/constants/ps-report-table-density.js +7 -0
- package/dist/constants/ps-table-sticky-config.d.ts +1 -0
- package/dist/constants/ps-table-sticky-config.js +1 -0
- package/dist/esm/components/ps-data-table.js +2 -4
- package/dist/esm/components/ps-report-table-skeleton.js +25 -0
- package/dist/esm/components/ps-report-table.js +41 -0
- package/dist/esm/constants/ps-report-column-align.js +5 -0
- package/dist/esm/constants/ps-report-row-kind.js +6 -0
- package/dist/esm/constants/ps-report-row-tone.js +6 -0
- package/dist/esm/constants/ps-report-table-classes.js +56 -0
- package/dist/esm/constants/ps-report-table-config.js +6 -0
- package/dist/esm/constants/ps-report-table-density.js +4 -0
- package/dist/esm/constants/ps-table-sticky-config.js +1 -0
- package/dist/esm/hooks/use-ps-sticky-head.js +22 -19
- package/dist/esm/index.js +8 -0
- package/dist/esm/interfaces/ps-report-cell-plan.js +1 -0
- package/dist/esm/interfaces/ps-report-column.js +1 -0
- package/dist/esm/interfaces/ps-table-sticky-head-inputs.js +1 -0
- package/dist/esm/services/ps-report-table-service.js +67 -0
- package/dist/esm/services/ps-table-sticky-head-service.js +13 -0
- package/dist/hooks/use-ps-sticky-head.d.ts +1 -1
- package/dist/hooks/use-ps-sticky-head.js +21 -18
- package/dist/index.d.ts +8 -0
- package/dist/index.js +8 -0
- package/dist/interfaces/ps-report-cell-plan.d.ts +6 -0
- package/dist/interfaces/ps-report-cell-plan.js +2 -0
- package/dist/interfaces/ps-report-column.d.ts +12 -0
- package/dist/interfaces/ps-report-column.js +2 -0
- package/dist/interfaces/ps-sticky-head-refs.d.ts +0 -1
- package/dist/interfaces/ps-table-sticky-head-inputs.d.ts +7 -0
- package/dist/interfaces/ps-table-sticky-head-inputs.js +2 -0
- package/dist/services/ps-report-table-service.d.ts +17 -0
- package/dist/services/ps-report-table-service.js +71 -0
- package/dist/services/ps-table-sticky-head-service.d.ts +3 -0
- package/dist/services/ps-table-sticky-head-service.js +13 -0
- package/package.json +1 -1
|
@@ -99,7 +99,6 @@ const PsDataTable = ({ caption, className, clearSelectionKey, columns, cursorPag
|
|
|
99
99
|
const [openedGroupKeys, setOpenedGroupKeys] = (0, react_1.useState)([]);
|
|
100
100
|
const [seenClearKey, setSeenClearKey] = (0, react_1.useState)(clearSelectionKey);
|
|
101
101
|
const stickyRegionRef = (0, react_1.useRef)(null);
|
|
102
|
-
const stickySentinelRef = (0, react_1.useRef)(null);
|
|
103
102
|
const stickyCardRef = (0, react_1.useRef)(null);
|
|
104
103
|
const stickyContentRef = (0, react_1.useRef)(null);
|
|
105
104
|
const stickyHeadRef = (0, react_1.useRef)(null);
|
|
@@ -130,13 +129,12 @@ const PsDataTable = ({ caption, className, clearSelectionKey, columns, cursorPag
|
|
|
130
129
|
const pins = ps_table_pin_service_1.PsTablePinService.leading(pinFirstColumn, Boolean(reorder), isSelectable);
|
|
131
130
|
const placementOf = (column, columnIndex) => ps_design_system_1.PallasoftClassNameService.merge(column.hideBelow === undefined ? '' : table_breakpoint_1.PsTableHideBelowClasses[column.hideBelow], columnIndex === 0 ? pins.first : '', ps_table_pin_service_1.PsTablePinService.end(column.pinEnd === true));
|
|
132
131
|
const overflow = (0, use_ps_table_overflow_1.usePsTableOverflow)(`${visibleColumns.map((column) => column.id).join(',')}:${rows.length}`);
|
|
133
|
-
|
|
132
|
+
(0, use_ps_sticky_head_1.usePsStickyHead)({
|
|
134
133
|
cardRef: stickyCardRef,
|
|
135
134
|
contentRef: stickyContentRef,
|
|
136
135
|
headRef: stickyHeadRef,
|
|
137
136
|
layoutKey: `${visibleColumns.map((column) => column.id).join(',')}:${rows.length}:${isLoading}`,
|
|
138
137
|
regionRef: stickyRegionRef,
|
|
139
|
-
sentinelRef: stickySentinelRef,
|
|
140
138
|
stickyTop,
|
|
141
139
|
});
|
|
142
140
|
const deferredSearch = (0, react_1.useDeferredValue)(search);
|
|
@@ -399,7 +397,7 @@ const PsDataTable = ({ caption, className, clearSelectionKey, columns, cursorPag
|
|
|
399
397
|
updateQuery({ search: next });
|
|
400
398
|
resetPage();
|
|
401
399
|
}, rows: rows, search: search, searchPlaceholder: searchPlaceholder })) : null, banner] }));
|
|
402
|
-
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: [stickyTop === undefined ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [stickyLeading, topContent] })) : ((0, jsx_runtime_1.
|
|
400
|
+
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: [stickyTop === undefined ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [stickyLeading, topContent] })) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('sticky z-sticky flex flex-col gap-3', stickyClassName), ref: stickyRegionRef, style: { top: stickyTop }, children: [stickyLeading, topContent] }) })), (0, jsx_runtime_1.jsx)("div", { className: 'min-w-0 overflow-clip rounded-[1.25rem]', children: (0, jsx_runtime_1.jsx)("div", { "aria-busy": isRefreshing, className: 'min-w-0 overflow-hidden rounded-[1.25rem] border border-line bg-surface', ref: stickyCardRef, children: (0, jsx_runtime_1.jsxs)("div", { ref: stickyContentRef, children: [showsPagination &&
|
|
403
401
|
paginationPosition !== ps_table_pagination_position_1.PsTablePaginationPosition.bottom &&
|
|
404
402
|
rowCount > ps_table_pagination_config_1.PsTablePaginationConfig.topMinRows
|
|
405
403
|
? renderPagination('border-b border-t-0')
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PsReportTableDensity } from '../constants/ps-report-table-density';
|
|
2
|
+
import type { PsReportColumn } from '../interfaces/ps-report-column';
|
|
3
|
+
export interface PsReportTableSkeletonProps<RowData> {
|
|
4
|
+
className?: string;
|
|
5
|
+
columns: PsReportColumn<RowData>[];
|
|
6
|
+
density?: PsReportTableDensity;
|
|
7
|
+
isFramed?: boolean;
|
|
8
|
+
rows?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare const PsReportTableSkeleton: <RowData>({ className, columns, density, isFramed, rows, }: PsReportTableSkeletonProps<RowData>) => import("react").JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsReportTableSkeleton = void 0;
|
|
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");
|
|
7
|
+
const ps_report_column_align_1 = require("../constants/ps-report-column-align");
|
|
8
|
+
const ps_report_table_classes_1 = require("../constants/ps-report-table-classes");
|
|
9
|
+
const ps_report_table_config_1 = require("../constants/ps-report-table-config");
|
|
10
|
+
const ps_report_table_density_1 = require("../constants/ps-report-table-density");
|
|
11
|
+
const ps_report_table_service_1 = require("../services/ps-report-table-service");
|
|
12
|
+
const PsReportTableSkeleton = ({ className, columns, density = ps_report_table_density_1.PsReportTableDensity.normal, isFramed = true, rows = ps_report_table_config_1.PsReportTableConfig.skeletonRows, }) => {
|
|
13
|
+
const isEnd = (column) => ps_report_table_service_1.PsReportTableService.alignOf(column) === ps_report_column_align_1.PsReportColumnAlign.right;
|
|
14
|
+
const headClass = (column, index) => {
|
|
15
|
+
if (isEnd(column))
|
|
16
|
+
return ps_report_table_classes_1.PsReportTableClasses.skeleton.headEnd;
|
|
17
|
+
return index === 0
|
|
18
|
+
? ps_report_table_classes_1.PsReportTableClasses.skeleton.headFirst
|
|
19
|
+
: ps_report_table_classes_1.PsReportTableClasses.skeleton.headOther;
|
|
20
|
+
};
|
|
21
|
+
const cellClass = (column, rowIndex, index) => isEnd(column)
|
|
22
|
+
? ps_report_table_classes_1.PsReportTableClasses.skeleton.cellEnd
|
|
23
|
+
: ps_report_table_classes_1.PsReportTableClasses.skeleton.cellWidths[(rowIndex + index) % ps_report_table_classes_1.PsReportTableClasses.skeleton.cellWidths.length];
|
|
24
|
+
return ((0, jsx_runtime_1.jsx)(ps_core_components_1.PsSkeletonGroup, { className: ps_design_system_1.PallasoftClassNameService.merge(isFramed ? ps_report_table_classes_1.PsReportTableClasses.frame : ps_report_table_classes_1.PsReportTableClasses.skeleton.plain, className), children: (0, jsx_runtime_1.jsxs)("table", { className: ps_report_table_classes_1.PsReportTableClasses.table, children: [(0, jsx_runtime_1.jsx)("thead", { className: ps_report_table_classes_1.PsReportTableClasses.head, children: (0, jsx_runtime_1.jsx)("tr", { children: columns.map((column, index) => ((0, jsx_runtime_1.jsx)("th", { className: ps_report_table_classes_1.PsReportTableClasses.headCell[density], style: ps_report_table_service_1.PsReportTableService.indent(0, density), children: (0, jsx_runtime_1.jsx)(ps_core_components_1.PsSkeleton, { className: headClass(column, index) }) }, column.id))) }) }), (0, jsx_runtime_1.jsx)("tbody", { className: ps_report_table_classes_1.PsReportTableClasses.body, children: Array.from({ length: rows }, (_, rowIndex) => ((0, jsx_runtime_1.jsx)("tr", { children: columns.map((column, index) => ((0, jsx_runtime_1.jsx)("td", { className: ps_report_table_classes_1.PsReportTableClasses.cell[density], style: {
|
|
25
|
+
...ps_report_table_service_1.PsReportTableService.columnStyle(column),
|
|
26
|
+
...ps_report_table_service_1.PsReportTableService.indent(0, density),
|
|
27
|
+
}, children: (0, jsx_runtime_1.jsx)(ps_core_components_1.PsSkeleton, { className: cellClass(column, rowIndex, index) }) }, column.id))) }, rowIndex))) })] }) }));
|
|
28
|
+
};
|
|
29
|
+
exports.PsReportTableSkeleton = PsReportTableSkeleton;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { PsReportRowKind } from '../constants/ps-report-row-kind';
|
|
3
|
+
import { PsReportRowTone } from '../constants/ps-report-row-tone';
|
|
4
|
+
import { PsReportTableDensity } from '../constants/ps-report-table-density';
|
|
5
|
+
import type { PsReportColumn } from '../interfaces/ps-report-column';
|
|
6
|
+
export interface PsReportTableProps<RowData> {
|
|
7
|
+
caption: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
columns: PsReportColumn<RowData>[];
|
|
10
|
+
density?: PsReportTableDensity;
|
|
11
|
+
emptyState?: ReactNode;
|
|
12
|
+
getLeadSpan?: (row: RowData) => number;
|
|
13
|
+
getRowId: (row: RowData) => string;
|
|
14
|
+
getRowKind?: (row: RowData) => PsReportRowKind;
|
|
15
|
+
getRowLevel?: (row: RowData) => number;
|
|
16
|
+
getRowTone?: (row: RowData) => PsReportRowTone;
|
|
17
|
+
isFirstColumnSticky?: boolean;
|
|
18
|
+
isFramed?: boolean;
|
|
19
|
+
isHeaderHidden?: boolean;
|
|
20
|
+
isHeaderSticky?: boolean;
|
|
21
|
+
isLoading?: boolean;
|
|
22
|
+
isRefreshing?: boolean;
|
|
23
|
+
maxHeight?: string;
|
|
24
|
+
minWidth?: string;
|
|
25
|
+
renderLead?: (row: RowData) => ReactNode;
|
|
26
|
+
rows: RowData[];
|
|
27
|
+
}
|
|
28
|
+
export declare const PsReportTable: <RowData>({ caption, className, columns, density, emptyState, getLeadSpan, getRowId, getRowKind, getRowLevel, getRowTone, isFirstColumnSticky, isFramed, isHeaderHidden, isHeaderSticky, isLoading, isRefreshing, maxHeight, minWidth, renderLead, rows, }: PsReportTableProps<RowData>) => import("react").JSX.Element;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsReportTable = 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_report_row_kind_1 = require("../constants/ps-report-row-kind");
|
|
7
|
+
const ps_report_row_tone_1 = require("../constants/ps-report-row-tone");
|
|
8
|
+
const ps_report_table_classes_1 = require("../constants/ps-report-table-classes");
|
|
9
|
+
const ps_report_table_config_1 = require("../constants/ps-report-table-config");
|
|
10
|
+
const ps_report_table_density_1 = require("../constants/ps-report-table-density");
|
|
11
|
+
const use_ps_table_overflow_1 = require("../hooks/use-ps-table-overflow");
|
|
12
|
+
const ps_report_table_service_1 = require("../services/ps-report-table-service");
|
|
13
|
+
const ps_report_table_skeleton_1 = require("./ps-report-table-skeleton");
|
|
14
|
+
const PsReportTable = ({ caption, className, columns, density = ps_report_table_density_1.PsReportTableDensity.normal, emptyState, getLeadSpan, getRowId, getRowKind, getRowLevel, getRowTone, isFirstColumnSticky = false, isFramed = true, isHeaderHidden = false, isHeaderSticky = false, isLoading = false, isRefreshing = false, maxHeight, minWidth, renderLead, rows, }) => {
|
|
15
|
+
const overflow = (0, use_ps_table_overflow_1.usePsTableOverflow)(String(rows.length));
|
|
16
|
+
if (isLoading)
|
|
17
|
+
return ((0, jsx_runtime_1.jsx)(ps_report_table_skeleton_1.PsReportTableSkeleton, { className: className, columns: columns, density: density, isFramed: isFramed }));
|
|
18
|
+
const kindOf = (row) => getRowKind !== undefined ? getRowKind(row) : ps_report_row_kind_1.PsReportRowKind.data;
|
|
19
|
+
const toneOf = (row) => getRowTone !== undefined ? getRowTone(row) : ps_report_row_tone_1.PsReportRowTone.neutral;
|
|
20
|
+
const levelOf = (row) => ps_report_table_service_1.PsReportTableService.levelOf(getRowLevel !== undefined ? getRowLevel(row) : undefined);
|
|
21
|
+
const leadOf = (row) => (getLeadSpan !== undefined ? getLeadSpan(row) : 1);
|
|
22
|
+
const renderRow = (row) => {
|
|
23
|
+
const kind = kindOf(row);
|
|
24
|
+
const tone = toneOf(row);
|
|
25
|
+
const level = levelOf(row);
|
|
26
|
+
return ((0, jsx_runtime_1.jsx)("tr", { className: ps_report_table_classes_1.PsReportTableClasses.kind[kind], children: ps_report_table_service_1.PsReportTableService.cells(columns, leadOf(row)).map((plan) => {
|
|
27
|
+
const className = ps_design_system_1.PallasoftClassNameService.merge(ps_report_table_service_1.PsReportTableService.cellClass(plan.column, plan.index, density, tone, isFirstColumnSticky), plan.index === 0 ? ps_report_table_classes_1.PsReportTableClasses.rowHeader : '');
|
|
28
|
+
const style = {
|
|
29
|
+
...ps_report_table_service_1.PsReportTableService.columnStyle(plan.column),
|
|
30
|
+
...(plan.index === 0 ? ps_report_table_service_1.PsReportTableService.indent(level, density) : {}),
|
|
31
|
+
};
|
|
32
|
+
return plan.index === 0 ? ((0, jsx_runtime_1.jsx)("th", { className: className, colSpan: plan.colSpan, scope: kind === ps_report_row_kind_1.PsReportRowKind.group && plan.colSpan === columns.length
|
|
33
|
+
? 'colgroup'
|
|
34
|
+
: 'row', style: style, children: plan.colSpan > 1 && renderLead !== undefined
|
|
35
|
+
? renderLead(row)
|
|
36
|
+
: plan.column.render(row) }, plan.column.id)) : ((0, jsx_runtime_1.jsx)("td", { className: className, colSpan: plan.colSpan, style: style, children: plan.column.render(row) }, plan.column.id));
|
|
37
|
+
}) }, getRowId(row)));
|
|
38
|
+
};
|
|
39
|
+
const content = ((0, jsx_runtime_1.jsx)("div", { className: ps_design_system_1.PallasoftClassNameService.merge(ps_report_table_classes_1.PsReportTableClasses.scroll, maxHeight !== undefined ? ps_report_table_classes_1.PsReportTableClasses.scrollBounded : '', isRefreshing ? ps_report_table_classes_1.PsReportTableClasses.refreshing : ''), "data-overflow-end": overflow.edges.end, "data-overflow-start": overflow.edges.start, onScroll: overflow.update, ref: overflow.ref, style: { maxHeight }, children: (0, jsx_runtime_1.jsxs)("table", { className: ps_report_table_classes_1.PsReportTableClasses.table, style: { minWidth }, children: [(0, jsx_runtime_1.jsx)("caption", { className: ps_report_table_classes_1.PsReportTableClasses.caption, children: caption }), (0, jsx_runtime_1.jsx)("thead", { className: ps_design_system_1.PallasoftClassNameService.merge(ps_report_table_classes_1.PsReportTableClasses.head, isHeaderHidden ? ps_report_table_classes_1.PsReportTableClasses.headHidden : ''), children: (0, jsx_runtime_1.jsx)("tr", { children: columns.map((column, index) => ((0, jsx_runtime_1.jsx)("th", { className: ps_report_table_service_1.PsReportTableService.headClass(column, index, density, isHeaderSticky, isFirstColumnSticky), scope: 'col', style: {
|
|
40
|
+
...ps_report_table_service_1.PsReportTableService.columnStyle(column),
|
|
41
|
+
...ps_report_table_service_1.PsReportTableService.indent(0, density),
|
|
42
|
+
}, children: column.label }, column.id))) }) }), (0, jsx_runtime_1.jsx)("tbody", { className: ps_report_table_classes_1.PsReportTableClasses.body, children: rows.length === 0 ? ((0, jsx_runtime_1.jsx)("tr", { children: (0, jsx_runtime_1.jsx)("td", { className: ps_report_table_classes_1.PsReportTableClasses.empty, colSpan: columns.length, children: emptyState !== undefined ? emptyState : ps_report_table_config_1.PsReportTableConfig.emptyLabel }) })) : (rows.map(renderRow)) })] }) }));
|
|
43
|
+
return ((0, jsx_runtime_1.jsx)("div", { "aria-busy": isRefreshing, className: ps_design_system_1.PallasoftClassNameService.merge(isFramed ? ps_report_table_classes_1.PsReportTableClasses.frame : ps_report_table_classes_1.PsReportTableClasses.framePlain, className), children: content }));
|
|
44
|
+
};
|
|
45
|
+
exports.PsReportTable = PsReportTable;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export declare const PsReportTableClasses: {
|
|
2
|
+
readonly align: {
|
|
3
|
+
readonly center: "text-center";
|
|
4
|
+
readonly left: "text-left";
|
|
5
|
+
readonly right: "text-right tabular-nums";
|
|
6
|
+
};
|
|
7
|
+
readonly body: "divide-y divide-line/60";
|
|
8
|
+
readonly caption: "sr-only";
|
|
9
|
+
readonly cell: {
|
|
10
|
+
readonly compact: "py-1.5 pr-3 text-[0.8125rem] leading-5";
|
|
11
|
+
readonly normal: "py-3 pr-5 text-sm";
|
|
12
|
+
};
|
|
13
|
+
readonly empty: "px-4 py-10 text-center text-sm text-ink/55";
|
|
14
|
+
readonly framePlain: "min-w-0";
|
|
15
|
+
readonly frame: "min-w-0 overflow-hidden rounded-[1.25rem] border border-line bg-surface";
|
|
16
|
+
readonly head: "bg-mist/70 text-[0.68rem] font-semibold uppercase tracking-[0.18em] text-ink/45";
|
|
17
|
+
readonly headCell: {
|
|
18
|
+
readonly compact: "py-2 pr-3 whitespace-nowrap";
|
|
19
|
+
readonly normal: "py-3.5 pr-5 whitespace-nowrap";
|
|
20
|
+
};
|
|
21
|
+
readonly headHidden: "sr-only";
|
|
22
|
+
readonly kind: {
|
|
23
|
+
readonly data: "text-ink";
|
|
24
|
+
readonly group: "bg-mist/40 font-semibold text-ink [--ps-table-pin-fill:inset_0_0_0_100vmax_rgb(var(--ps-color-mist-rgb)/0.4)]";
|
|
25
|
+
readonly subtotal: "border-t border-line font-semibold text-ink";
|
|
26
|
+
readonly total: "border-t-2 border-line bg-mist/50 font-semibold text-ink [--ps-table-pin-fill:inset_0_0_0_100vmax_rgb(var(--ps-color-mist-rgb)/0.5)]";
|
|
27
|
+
};
|
|
28
|
+
readonly nowrap: "whitespace-nowrap";
|
|
29
|
+
readonly refreshing: "opacity-60";
|
|
30
|
+
readonly rowHeader: "[font-weight:inherit]";
|
|
31
|
+
readonly scroll: "ps-scrollbar overflow-x-auto overscroll-x-contain";
|
|
32
|
+
readonly scrollBounded: "overflow-y-auto overscroll-contain";
|
|
33
|
+
readonly skeleton: {
|
|
34
|
+
readonly cellEnd: "ml-auto w-16";
|
|
35
|
+
readonly cellWidths: readonly ["w-3/4", "w-1/2"];
|
|
36
|
+
readonly headEnd: "ml-auto h-2.5 w-12";
|
|
37
|
+
readonly headFirst: "h-2.5 w-20";
|
|
38
|
+
readonly headOther: "h-2.5 w-14";
|
|
39
|
+
readonly plain: "min-w-0 overflow-hidden";
|
|
40
|
+
};
|
|
41
|
+
readonly stickyFirstBody: "ps-table-pin left-0";
|
|
42
|
+
readonly stickyFirstHead: "ps-table-pin left-0 top-0 z-[3]";
|
|
43
|
+
readonly stickyHead: "ps-table-pin top-0 z-[2]";
|
|
44
|
+
readonly table: "w-full border-collapse text-left";
|
|
45
|
+
readonly tone: {
|
|
46
|
+
readonly danger: "bg-danger-soft/60 text-danger [--ps-table-pin-fill:inset_0_0_0_100vmax_rgb(var(--ps-color-danger-soft-rgb)/0.6)]";
|
|
47
|
+
readonly muted: "text-ink/60";
|
|
48
|
+
readonly neutral: "";
|
|
49
|
+
readonly primary: "bg-primary/10 text-primary [--ps-table-pin-fill:inset_0_0_0_100vmax_rgb(var(--ps-color-primary-rgb)/0.1)]";
|
|
50
|
+
};
|
|
51
|
+
readonly truncate: "truncate";
|
|
52
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsReportTableClasses = void 0;
|
|
4
|
+
const ps_report_column_align_1 = require("./ps-report-column-align");
|
|
5
|
+
const ps_report_row_kind_1 = require("./ps-report-row-kind");
|
|
6
|
+
const ps_report_row_tone_1 = require("./ps-report-row-tone");
|
|
7
|
+
const ps_report_table_density_1 = require("./ps-report-table-density");
|
|
8
|
+
exports.PsReportTableClasses = {
|
|
9
|
+
align: {
|
|
10
|
+
[ps_report_column_align_1.PsReportColumnAlign.center]: 'text-center',
|
|
11
|
+
[ps_report_column_align_1.PsReportColumnAlign.left]: 'text-left',
|
|
12
|
+
[ps_report_column_align_1.PsReportColumnAlign.right]: 'text-right tabular-nums',
|
|
13
|
+
},
|
|
14
|
+
body: 'divide-y divide-line/60',
|
|
15
|
+
caption: 'sr-only',
|
|
16
|
+
cell: {
|
|
17
|
+
[ps_report_table_density_1.PsReportTableDensity.compact]: 'py-1.5 pr-3 text-[0.8125rem] leading-5',
|
|
18
|
+
[ps_report_table_density_1.PsReportTableDensity.normal]: 'py-3 pr-5 text-sm',
|
|
19
|
+
},
|
|
20
|
+
empty: 'px-4 py-10 text-center text-sm text-ink/55',
|
|
21
|
+
framePlain: 'min-w-0',
|
|
22
|
+
frame: 'min-w-0 overflow-hidden rounded-[1.25rem] border border-line bg-surface',
|
|
23
|
+
head: 'bg-mist/70 text-[0.68rem] font-semibold uppercase tracking-[0.18em] text-ink/45',
|
|
24
|
+
headCell: {
|
|
25
|
+
[ps_report_table_density_1.PsReportTableDensity.compact]: 'py-2 pr-3 whitespace-nowrap',
|
|
26
|
+
[ps_report_table_density_1.PsReportTableDensity.normal]: 'py-3.5 pr-5 whitespace-nowrap',
|
|
27
|
+
},
|
|
28
|
+
headHidden: 'sr-only',
|
|
29
|
+
kind: {
|
|
30
|
+
[ps_report_row_kind_1.PsReportRowKind.data]: 'text-ink',
|
|
31
|
+
[ps_report_row_kind_1.PsReportRowKind.group]: 'bg-mist/40 font-semibold text-ink [--ps-table-pin-fill:inset_0_0_0_100vmax_rgb(var(--ps-color-mist-rgb)/0.4)]',
|
|
32
|
+
[ps_report_row_kind_1.PsReportRowKind.subtotal]: 'border-t border-line font-semibold text-ink',
|
|
33
|
+
[ps_report_row_kind_1.PsReportRowKind.total]: 'border-t-2 border-line bg-mist/50 font-semibold text-ink [--ps-table-pin-fill:inset_0_0_0_100vmax_rgb(var(--ps-color-mist-rgb)/0.5)]',
|
|
34
|
+
},
|
|
35
|
+
nowrap: 'whitespace-nowrap',
|
|
36
|
+
refreshing: 'opacity-60',
|
|
37
|
+
rowHeader: '[font-weight:inherit]',
|
|
38
|
+
scroll: 'ps-scrollbar overflow-x-auto overscroll-x-contain',
|
|
39
|
+
scrollBounded: 'overflow-y-auto overscroll-contain',
|
|
40
|
+
skeleton: {
|
|
41
|
+
cellEnd: 'ml-auto w-16',
|
|
42
|
+
cellWidths: ['w-3/4', 'w-1/2'],
|
|
43
|
+
headEnd: 'ml-auto h-2.5 w-12',
|
|
44
|
+
headFirst: 'h-2.5 w-20',
|
|
45
|
+
headOther: 'h-2.5 w-14',
|
|
46
|
+
plain: 'min-w-0 overflow-hidden',
|
|
47
|
+
},
|
|
48
|
+
stickyFirstBody: 'ps-table-pin left-0',
|
|
49
|
+
stickyFirstHead: 'ps-table-pin left-0 top-0 z-[3]',
|
|
50
|
+
stickyHead: 'ps-table-pin top-0 z-[2]',
|
|
51
|
+
table: 'w-full border-collapse text-left',
|
|
52
|
+
tone: {
|
|
53
|
+
[ps_report_row_tone_1.PsReportRowTone.danger]: 'bg-danger-soft/60 text-danger [--ps-table-pin-fill:inset_0_0_0_100vmax_rgb(var(--ps-color-danger-soft-rgb)/0.6)]',
|
|
54
|
+
[ps_report_row_tone_1.PsReportRowTone.muted]: 'text-ink/60',
|
|
55
|
+
[ps_report_row_tone_1.PsReportRowTone.neutral]: '',
|
|
56
|
+
[ps_report_row_tone_1.PsReportRowTone.primary]: 'bg-primary/10 text-primary [--ps-table-pin-fill:inset_0_0_0_100vmax_rgb(var(--ps-color-primary-rgb)/0.1)]',
|
|
57
|
+
},
|
|
58
|
+
truncate: 'truncate',
|
|
59
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsReportTableConfig = void 0;
|
|
4
|
+
exports.PsReportTableConfig = {
|
|
5
|
+
baseIndentRem: { compact: 0.75, normal: 1.25 },
|
|
6
|
+
emptyLabel: 'Nothing to show',
|
|
7
|
+
indentRem: 1.25,
|
|
8
|
+
skeletonRows: 6,
|
|
9
|
+
};
|
|
@@ -63,7 +63,6 @@ export const PsDataTable = ({ caption, className, clearSelectionKey, columns, cu
|
|
|
63
63
|
const [openedGroupKeys, setOpenedGroupKeys] = useState([]);
|
|
64
64
|
const [seenClearKey, setSeenClearKey] = useState(clearSelectionKey);
|
|
65
65
|
const stickyRegionRef = useRef(null);
|
|
66
|
-
const stickySentinelRef = useRef(null);
|
|
67
66
|
const stickyCardRef = useRef(null);
|
|
68
67
|
const stickyContentRef = useRef(null);
|
|
69
68
|
const stickyHeadRef = useRef(null);
|
|
@@ -94,13 +93,12 @@ export const PsDataTable = ({ caption, className, clearSelectionKey, columns, cu
|
|
|
94
93
|
const pins = PsTablePinService.leading(pinFirstColumn, Boolean(reorder), isSelectable);
|
|
95
94
|
const placementOf = (column, columnIndex) => PallasoftClassNameService.merge(column.hideBelow === undefined ? '' : PsTableHideBelowClasses[column.hideBelow], columnIndex === 0 ? pins.first : '', PsTablePinService.end(column.pinEnd === true));
|
|
96
95
|
const overflow = usePsTableOverflow(`${visibleColumns.map((column) => column.id).join(',')}:${rows.length}`);
|
|
97
|
-
|
|
96
|
+
usePsStickyHead({
|
|
98
97
|
cardRef: stickyCardRef,
|
|
99
98
|
contentRef: stickyContentRef,
|
|
100
99
|
headRef: stickyHeadRef,
|
|
101
100
|
layoutKey: `${visibleColumns.map((column) => column.id).join(',')}:${rows.length}:${isLoading}`,
|
|
102
101
|
regionRef: stickyRegionRef,
|
|
103
|
-
sentinelRef: stickySentinelRef,
|
|
104
102
|
stickyTop,
|
|
105
103
|
});
|
|
106
104
|
const deferredSearch = useDeferredValue(search);
|
|
@@ -363,7 +361,7 @@ export const PsDataTable = ({ caption, className, clearSelectionKey, columns, cu
|
|
|
363
361
|
updateQuery({ search: next });
|
|
364
362
|
resetPage();
|
|
365
363
|
}, rows: rows, search: search, searchPlaceholder: searchPlaceholder })) : null, banner] }));
|
|
366
|
-
return (_jsxs("div", { ref: containerRef, className: PallasoftClassNameService.merge('flex min-w-0 flex-col gap-3', className), children: [stickyTop === undefined ? (_jsxs(_Fragment, { children: [stickyLeading, topContent] })) : (
|
|
364
|
+
return (_jsxs("div", { ref: containerRef, className: PallasoftClassNameService.merge('flex min-w-0 flex-col gap-3', className), children: [stickyTop === undefined ? (_jsxs(_Fragment, { children: [stickyLeading, topContent] })) : (_jsx(_Fragment, { children: _jsxs("div", { className: PallasoftClassNameService.merge('sticky z-sticky flex flex-col gap-3', stickyClassName), ref: stickyRegionRef, style: { top: stickyTop }, children: [stickyLeading, topContent] }) })), _jsx("div", { className: 'min-w-0 overflow-clip rounded-[1.25rem]', children: _jsx("div", { "aria-busy": isRefreshing, className: 'min-w-0 overflow-hidden rounded-[1.25rem] border border-line bg-surface', ref: stickyCardRef, children: _jsxs("div", { ref: stickyContentRef, children: [showsPagination &&
|
|
367
365
|
paginationPosition !== PsTablePaginationPosition.bottom &&
|
|
368
366
|
rowCount > PsTablePaginationConfig.topMinRows
|
|
369
367
|
? renderPagination('border-b border-t-0')
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { PsSkeleton, PsSkeletonGroup } from '@pallasoft/ps-core-components';
|
|
3
|
+
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
4
|
+
import { PsReportColumnAlign } from '../constants/ps-report-column-align';
|
|
5
|
+
import { PsReportTableClasses } from '../constants/ps-report-table-classes';
|
|
6
|
+
import { PsReportTableConfig } from '../constants/ps-report-table-config';
|
|
7
|
+
import { PsReportTableDensity } from '../constants/ps-report-table-density';
|
|
8
|
+
import { PsReportTableService } from '../services/ps-report-table-service';
|
|
9
|
+
export const PsReportTableSkeleton = ({ className, columns, density = PsReportTableDensity.normal, isFramed = true, rows = PsReportTableConfig.skeletonRows, }) => {
|
|
10
|
+
const isEnd = (column) => PsReportTableService.alignOf(column) === PsReportColumnAlign.right;
|
|
11
|
+
const headClass = (column, index) => {
|
|
12
|
+
if (isEnd(column))
|
|
13
|
+
return PsReportTableClasses.skeleton.headEnd;
|
|
14
|
+
return index === 0
|
|
15
|
+
? PsReportTableClasses.skeleton.headFirst
|
|
16
|
+
: PsReportTableClasses.skeleton.headOther;
|
|
17
|
+
};
|
|
18
|
+
const cellClass = (column, rowIndex, index) => isEnd(column)
|
|
19
|
+
? PsReportTableClasses.skeleton.cellEnd
|
|
20
|
+
: PsReportTableClasses.skeleton.cellWidths[(rowIndex + index) % PsReportTableClasses.skeleton.cellWidths.length];
|
|
21
|
+
return (_jsx(PsSkeletonGroup, { className: PallasoftClassNameService.merge(isFramed ? PsReportTableClasses.frame : PsReportTableClasses.skeleton.plain, className), children: _jsxs("table", { className: PsReportTableClasses.table, children: [_jsx("thead", { className: PsReportTableClasses.head, children: _jsx("tr", { children: columns.map((column, index) => (_jsx("th", { className: PsReportTableClasses.headCell[density], style: PsReportTableService.indent(0, density), children: _jsx(PsSkeleton, { className: headClass(column, index) }) }, column.id))) }) }), _jsx("tbody", { className: PsReportTableClasses.body, children: Array.from({ length: rows }, (_, rowIndex) => (_jsx("tr", { children: columns.map((column, index) => (_jsx("td", { className: PsReportTableClasses.cell[density], style: {
|
|
22
|
+
...PsReportTableService.columnStyle(column),
|
|
23
|
+
...PsReportTableService.indent(0, density),
|
|
24
|
+
}, children: _jsx(PsSkeleton, { className: cellClass(column, rowIndex, index) }) }, column.id))) }, rowIndex))) })] }) }));
|
|
25
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
3
|
+
import { PsReportRowKind } from '../constants/ps-report-row-kind';
|
|
4
|
+
import { PsReportRowTone } from '../constants/ps-report-row-tone';
|
|
5
|
+
import { PsReportTableClasses } from '../constants/ps-report-table-classes';
|
|
6
|
+
import { PsReportTableConfig } from '../constants/ps-report-table-config';
|
|
7
|
+
import { PsReportTableDensity } from '../constants/ps-report-table-density';
|
|
8
|
+
import { usePsTableOverflow } from '../hooks/use-ps-table-overflow';
|
|
9
|
+
import { PsReportTableService } from '../services/ps-report-table-service';
|
|
10
|
+
import { PsReportTableSkeleton } from './ps-report-table-skeleton';
|
|
11
|
+
export const PsReportTable = ({ caption, className, columns, density = PsReportTableDensity.normal, emptyState, getLeadSpan, getRowId, getRowKind, getRowLevel, getRowTone, isFirstColumnSticky = false, isFramed = true, isHeaderHidden = false, isHeaderSticky = false, isLoading = false, isRefreshing = false, maxHeight, minWidth, renderLead, rows, }) => {
|
|
12
|
+
const overflow = usePsTableOverflow(String(rows.length));
|
|
13
|
+
if (isLoading)
|
|
14
|
+
return (_jsx(PsReportTableSkeleton, { className: className, columns: columns, density: density, isFramed: isFramed }));
|
|
15
|
+
const kindOf = (row) => getRowKind !== undefined ? getRowKind(row) : PsReportRowKind.data;
|
|
16
|
+
const toneOf = (row) => getRowTone !== undefined ? getRowTone(row) : PsReportRowTone.neutral;
|
|
17
|
+
const levelOf = (row) => PsReportTableService.levelOf(getRowLevel !== undefined ? getRowLevel(row) : undefined);
|
|
18
|
+
const leadOf = (row) => (getLeadSpan !== undefined ? getLeadSpan(row) : 1);
|
|
19
|
+
const renderRow = (row) => {
|
|
20
|
+
const kind = kindOf(row);
|
|
21
|
+
const tone = toneOf(row);
|
|
22
|
+
const level = levelOf(row);
|
|
23
|
+
return (_jsx("tr", { className: PsReportTableClasses.kind[kind], children: PsReportTableService.cells(columns, leadOf(row)).map((plan) => {
|
|
24
|
+
const className = PallasoftClassNameService.merge(PsReportTableService.cellClass(plan.column, plan.index, density, tone, isFirstColumnSticky), plan.index === 0 ? PsReportTableClasses.rowHeader : '');
|
|
25
|
+
const style = {
|
|
26
|
+
...PsReportTableService.columnStyle(plan.column),
|
|
27
|
+
...(plan.index === 0 ? PsReportTableService.indent(level, density) : {}),
|
|
28
|
+
};
|
|
29
|
+
return plan.index === 0 ? (_jsx("th", { className: className, colSpan: plan.colSpan, scope: kind === PsReportRowKind.group && plan.colSpan === columns.length
|
|
30
|
+
? 'colgroup'
|
|
31
|
+
: 'row', style: style, children: plan.colSpan > 1 && renderLead !== undefined
|
|
32
|
+
? renderLead(row)
|
|
33
|
+
: plan.column.render(row) }, plan.column.id)) : (_jsx("td", { className: className, colSpan: plan.colSpan, style: style, children: plan.column.render(row) }, plan.column.id));
|
|
34
|
+
}) }, getRowId(row)));
|
|
35
|
+
};
|
|
36
|
+
const content = (_jsx("div", { className: PallasoftClassNameService.merge(PsReportTableClasses.scroll, maxHeight !== undefined ? PsReportTableClasses.scrollBounded : '', isRefreshing ? PsReportTableClasses.refreshing : ''), "data-overflow-end": overflow.edges.end, "data-overflow-start": overflow.edges.start, onScroll: overflow.update, ref: overflow.ref, style: { maxHeight }, children: _jsxs("table", { className: PsReportTableClasses.table, style: { minWidth }, children: [_jsx("caption", { className: PsReportTableClasses.caption, children: caption }), _jsx("thead", { className: PallasoftClassNameService.merge(PsReportTableClasses.head, isHeaderHidden ? PsReportTableClasses.headHidden : ''), children: _jsx("tr", { children: columns.map((column, index) => (_jsx("th", { className: PsReportTableService.headClass(column, index, density, isHeaderSticky, isFirstColumnSticky), scope: 'col', style: {
|
|
37
|
+
...PsReportTableService.columnStyle(column),
|
|
38
|
+
...PsReportTableService.indent(0, density),
|
|
39
|
+
}, children: column.label }, column.id))) }) }), _jsx("tbody", { className: PsReportTableClasses.body, children: rows.length === 0 ? (_jsx("tr", { children: _jsx("td", { className: PsReportTableClasses.empty, colSpan: columns.length, children: emptyState !== undefined ? emptyState : PsReportTableConfig.emptyLabel }) })) : (rows.map(renderRow)) })] }) }));
|
|
40
|
+
return (_jsx("div", { "aria-busy": isRefreshing, className: PallasoftClassNameService.merge(isFramed ? PsReportTableClasses.frame : PsReportTableClasses.framePlain, className), children: content }));
|
|
41
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { PsReportColumnAlign } from './ps-report-column-align';
|
|
2
|
+
import { PsReportRowKind } from './ps-report-row-kind';
|
|
3
|
+
import { PsReportRowTone } from './ps-report-row-tone';
|
|
4
|
+
import { PsReportTableDensity } from './ps-report-table-density';
|
|
5
|
+
export const PsReportTableClasses = {
|
|
6
|
+
align: {
|
|
7
|
+
[PsReportColumnAlign.center]: 'text-center',
|
|
8
|
+
[PsReportColumnAlign.left]: 'text-left',
|
|
9
|
+
[PsReportColumnAlign.right]: 'text-right tabular-nums',
|
|
10
|
+
},
|
|
11
|
+
body: 'divide-y divide-line/60',
|
|
12
|
+
caption: 'sr-only',
|
|
13
|
+
cell: {
|
|
14
|
+
[PsReportTableDensity.compact]: 'py-1.5 pr-3 text-[0.8125rem] leading-5',
|
|
15
|
+
[PsReportTableDensity.normal]: 'py-3 pr-5 text-sm',
|
|
16
|
+
},
|
|
17
|
+
empty: 'px-4 py-10 text-center text-sm text-ink/55',
|
|
18
|
+
framePlain: 'min-w-0',
|
|
19
|
+
frame: 'min-w-0 overflow-hidden rounded-[1.25rem] border border-line bg-surface',
|
|
20
|
+
head: 'bg-mist/70 text-[0.68rem] font-semibold uppercase tracking-[0.18em] text-ink/45',
|
|
21
|
+
headCell: {
|
|
22
|
+
[PsReportTableDensity.compact]: 'py-2 pr-3 whitespace-nowrap',
|
|
23
|
+
[PsReportTableDensity.normal]: 'py-3.5 pr-5 whitespace-nowrap',
|
|
24
|
+
},
|
|
25
|
+
headHidden: 'sr-only',
|
|
26
|
+
kind: {
|
|
27
|
+
[PsReportRowKind.data]: 'text-ink',
|
|
28
|
+
[PsReportRowKind.group]: 'bg-mist/40 font-semibold text-ink [--ps-table-pin-fill:inset_0_0_0_100vmax_rgb(var(--ps-color-mist-rgb)/0.4)]',
|
|
29
|
+
[PsReportRowKind.subtotal]: 'border-t border-line font-semibold text-ink',
|
|
30
|
+
[PsReportRowKind.total]: 'border-t-2 border-line bg-mist/50 font-semibold text-ink [--ps-table-pin-fill:inset_0_0_0_100vmax_rgb(var(--ps-color-mist-rgb)/0.5)]',
|
|
31
|
+
},
|
|
32
|
+
nowrap: 'whitespace-nowrap',
|
|
33
|
+
refreshing: 'opacity-60',
|
|
34
|
+
rowHeader: '[font-weight:inherit]',
|
|
35
|
+
scroll: 'ps-scrollbar overflow-x-auto overscroll-x-contain',
|
|
36
|
+
scrollBounded: 'overflow-y-auto overscroll-contain',
|
|
37
|
+
skeleton: {
|
|
38
|
+
cellEnd: 'ml-auto w-16',
|
|
39
|
+
cellWidths: ['w-3/4', 'w-1/2'],
|
|
40
|
+
headEnd: 'ml-auto h-2.5 w-12',
|
|
41
|
+
headFirst: 'h-2.5 w-20',
|
|
42
|
+
headOther: 'h-2.5 w-14',
|
|
43
|
+
plain: 'min-w-0 overflow-hidden',
|
|
44
|
+
},
|
|
45
|
+
stickyFirstBody: 'ps-table-pin left-0',
|
|
46
|
+
stickyFirstHead: 'ps-table-pin left-0 top-0 z-[3]',
|
|
47
|
+
stickyHead: 'ps-table-pin top-0 z-[2]',
|
|
48
|
+
table: 'w-full border-collapse text-left',
|
|
49
|
+
tone: {
|
|
50
|
+
[PsReportRowTone.danger]: 'bg-danger-soft/60 text-danger [--ps-table-pin-fill:inset_0_0_0_100vmax_rgb(var(--ps-color-danger-soft-rgb)/0.6)]',
|
|
51
|
+
[PsReportRowTone.muted]: 'text-ink/60',
|
|
52
|
+
[PsReportRowTone.neutral]: '',
|
|
53
|
+
[PsReportRowTone.primary]: 'bg-primary/10 text-primary [--ps-table-pin-fill:inset_0_0_0_100vmax_rgb(var(--ps-color-primary-rgb)/0.1)]',
|
|
54
|
+
},
|
|
55
|
+
truncate: 'truncate',
|
|
56
|
+
};
|
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
import { useLayoutEffect
|
|
1
|
+
import { useLayoutEffect } from 'react';
|
|
2
2
|
import { PsTableStickyConfig } from '../constants/ps-table-sticky-config';
|
|
3
3
|
import { PsTableScrollService } from '../services/ps-table-scroll-service';
|
|
4
4
|
import { PsTableStickyHeadService } from '../services/ps-table-sticky-head-service';
|
|
5
|
-
export const usePsStickyHead = ({ cardRef, contentRef, headRef, layoutKey, regionRef,
|
|
6
|
-
const [isStuck, setIsStuck] = useState(false);
|
|
5
|
+
export const usePsStickyHead = ({ cardRef, contentRef, headRef, layoutKey, regionRef, stickyTop, }) => {
|
|
7
6
|
useLayoutEffect(() => {
|
|
8
7
|
const region = regionRef.current;
|
|
9
|
-
const sentinel = sentinelRef.current;
|
|
10
8
|
const card = cardRef.current;
|
|
11
9
|
const content = contentRef.current;
|
|
12
10
|
const head = headRef.current;
|
|
13
11
|
const table = head === null ? null : head.parentElement;
|
|
14
12
|
if (stickyTop === undefined ||
|
|
15
13
|
region === null ||
|
|
16
|
-
sentinel === null ||
|
|
17
14
|
card === null ||
|
|
18
15
|
content === null ||
|
|
19
16
|
head === null ||
|
|
@@ -23,6 +20,7 @@ export const usePsStickyHead = ({ cardRef, contentRef, headRef, layoutKey, regio
|
|
|
23
20
|
const Timeline = window.ScrollTimeline;
|
|
24
21
|
const isDriven = scroller !== null && Timeline !== undefined;
|
|
25
22
|
let animations = [];
|
|
23
|
+
let measured = null;
|
|
26
24
|
let frame = 0;
|
|
27
25
|
const headTravel = () => Math.max(table.offsetHeight - head.offsetHeight, 0);
|
|
28
26
|
const drive = () => {
|
|
@@ -32,10 +30,19 @@ export const usePsStickyHead = ({ cardRef, contentRef, headRef, layoutKey, regio
|
|
|
32
30
|
Number.parseFloat(getComputedStyle(region).top) +
|
|
33
31
|
region.offsetHeight +
|
|
34
32
|
PsTableStickyConfig.cardGapPx;
|
|
35
|
-
const
|
|
33
|
+
const inputs = {
|
|
34
|
+
cardPin: content.getBoundingClientRect().top + scroller.scrollTop - pinnedLine,
|
|
35
|
+
cardTravel: card.offsetHeight,
|
|
36
|
+
headPin: table.getBoundingClientRect().top + scroller.scrollTop - pinnedLine,
|
|
37
|
+
headTravel: headTravel(),
|
|
38
|
+
scrollRange: scroller.scrollHeight - scroller.clientHeight,
|
|
39
|
+
};
|
|
40
|
+
if (PsTableStickyHeadService.sameInputs(measured, inputs))
|
|
41
|
+
return;
|
|
42
|
+
measured = inputs;
|
|
36
43
|
const timeline = new Timeline({ axis: 'block', source: scroller });
|
|
37
|
-
const headFrames = PsTableStickyHeadService.keyframes(
|
|
38
|
-
const cardFrames = PsTableStickyHeadService.keyframes(
|
|
44
|
+
const headFrames = PsTableStickyHeadService.keyframes(inputs.headPin, inputs.headTravel, inputs.scrollRange);
|
|
45
|
+
const cardFrames = PsTableStickyHeadService.keyframes(inputs.cardPin, inputs.cardTravel, inputs.scrollRange);
|
|
39
46
|
animations.forEach((animation) => animation.cancel());
|
|
40
47
|
animations = [
|
|
41
48
|
head.animate(headFrames.map((keyframe) => ({
|
|
@@ -53,26 +60,22 @@ export const usePsStickyHead = ({ cardRef, contentRef, headRef, layoutKey, regio
|
|
|
53
60
|
];
|
|
54
61
|
};
|
|
55
62
|
const follow = () => {
|
|
63
|
+
frame = 0;
|
|
56
64
|
const pinnedLine = region.getBoundingClientRect().bottom + PsTableStickyConfig.cardGapPx;
|
|
57
65
|
head.style.transform = `translateY(${PsTableStickyHeadService.offset(pinnedLine, table.getBoundingClientRect().top, table.offsetHeight, head.offsetHeight)}px)`;
|
|
58
66
|
const cut = PsTableStickyHeadService.offset(pinnedLine, content.getBoundingClientRect().top, card.offsetHeight, 0);
|
|
59
67
|
card.style.transform = `translateY(${cut}px)`;
|
|
60
68
|
content.style.transform = `translateY(${-cut}px)`;
|
|
61
69
|
};
|
|
62
|
-
const check = () => {
|
|
63
|
-
frame = 0;
|
|
64
|
-
setIsStuck(sentinel.getBoundingClientRect().top < region.getBoundingClientRect().top - 1);
|
|
65
|
-
if (!isDriven)
|
|
66
|
-
follow();
|
|
67
|
-
};
|
|
68
70
|
const schedule = () => {
|
|
69
71
|
if (frame === 0)
|
|
70
|
-
frame = window.requestAnimationFrame(
|
|
72
|
+
frame = window.requestAnimationFrame(follow);
|
|
71
73
|
};
|
|
72
74
|
const measure = () => {
|
|
73
75
|
if (isDriven)
|
|
74
76
|
drive();
|
|
75
|
-
|
|
77
|
+
else
|
|
78
|
+
schedule();
|
|
76
79
|
};
|
|
77
80
|
const observer = new ResizeObserver(measure);
|
|
78
81
|
measure();
|
|
@@ -80,8 +83,9 @@ export const usePsStickyHead = ({ cardRef, contentRef, headRef, layoutKey, regio
|
|
|
80
83
|
observer.observe(card);
|
|
81
84
|
if (scroller !== null)
|
|
82
85
|
Array.from(scroller.children).forEach((child) => observer.observe(child));
|
|
83
|
-
window.addEventListener('scroll', schedule, { capture: true, passive: true });
|
|
84
86
|
window.addEventListener('resize', measure);
|
|
87
|
+
if (!isDriven)
|
|
88
|
+
window.addEventListener('scroll', schedule, { capture: true, passive: true });
|
|
85
89
|
return () => {
|
|
86
90
|
observer.disconnect();
|
|
87
91
|
animations.forEach((animation) => animation.cancel());
|
|
@@ -93,6 +97,5 @@ export const usePsStickyHead = ({ cardRef, contentRef, headRef, layoutKey, regio
|
|
|
93
97
|
if (frame !== 0)
|
|
94
98
|
window.cancelAnimationFrame(frame);
|
|
95
99
|
};
|
|
96
|
-
}, [cardRef, contentRef, headRef, layoutKey, regionRef,
|
|
97
|
-
return isStuck;
|
|
100
|
+
}, [cardRef, contentRef, headRef, layoutKey, regionRef, stickyTop]);
|
|
98
101
|
};
|
package/dist/esm/index.js
CHANGED
|
@@ -64,3 +64,11 @@ export * from './interfaces/ps-server-rows-result';
|
|
|
64
64
|
export * from './interfaces/ps-table-cursor-paging';
|
|
65
65
|
export * from './interfaces/ps-table-select-all-matching';
|
|
66
66
|
export * from './services/ps-server-rows-service';
|
|
67
|
+
export * from './components/ps-report-table';
|
|
68
|
+
export * from './components/ps-report-table-skeleton';
|
|
69
|
+
export * from './constants/ps-report-column-align';
|
|
70
|
+
export * from './constants/ps-report-row-kind';
|
|
71
|
+
export * from './constants/ps-report-row-tone';
|
|
72
|
+
export * from './constants/ps-report-table-density';
|
|
73
|
+
export * from './interfaces/ps-report-column';
|
|
74
|
+
export * from './services/ps-report-table-service';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { PsReportColumnAlign } from '../constants/ps-report-column-align';
|
|
2
|
+
import { PsReportTableClasses } from '../constants/ps-report-table-classes';
|
|
3
|
+
import { PsReportTableConfig } from '../constants/ps-report-table-config';
|
|
4
|
+
import { PsTablePinClasses } from '../constants/ps-table-pin-classes';
|
|
5
|
+
export class PsReportTableService {
|
|
6
|
+
static cells(columns, leadSpan) {
|
|
7
|
+
const span = PsReportTableService.span(columns.length, leadSpan);
|
|
8
|
+
const plan = [{ colSpan: span, column: columns[0], index: 0 }];
|
|
9
|
+
for (let index = span; index < columns.length; index += 1)
|
|
10
|
+
plan.push({ colSpan: 1, column: columns[index], index });
|
|
11
|
+
return plan;
|
|
12
|
+
}
|
|
13
|
+
static span(count, leadSpan) {
|
|
14
|
+
return Math.min(Math.max(leadSpan, 1), count);
|
|
15
|
+
}
|
|
16
|
+
static indent(level, density) {
|
|
17
|
+
const base = PsReportTableConfig.baseIndentRem[density];
|
|
18
|
+
return { paddingLeft: `${base + level * PsReportTableConfig.indentRem}rem` };
|
|
19
|
+
}
|
|
20
|
+
static columnStyle(column) {
|
|
21
|
+
return {
|
|
22
|
+
maxWidth: column.maxWidth,
|
|
23
|
+
minWidth: column.minWidth,
|
|
24
|
+
width: column.width,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
static levelOf(level) {
|
|
28
|
+
return level !== undefined && level > 0 ? level : 0;
|
|
29
|
+
}
|
|
30
|
+
static headClass(column, index, density, isHeaderSticky, isFirstColumnSticky) {
|
|
31
|
+
const isPinnedFirst = index === 0 && isFirstColumnSticky;
|
|
32
|
+
const pin = PsReportTableService.headPin(isHeaderSticky, isPinnedFirst);
|
|
33
|
+
return [
|
|
34
|
+
PsReportTableClasses.headCell[density],
|
|
35
|
+
PsReportTableClasses.align[PsReportTableService.alignOf(column)],
|
|
36
|
+
pin,
|
|
37
|
+
isPinnedFirst ? PsTablePinClasses.edge : '',
|
|
38
|
+
]
|
|
39
|
+
.filter((name) => name !== '')
|
|
40
|
+
.join(' ');
|
|
41
|
+
}
|
|
42
|
+
static headPin(isHeaderSticky, isPinnedFirst) {
|
|
43
|
+
if (isHeaderSticky && isPinnedFirst)
|
|
44
|
+
return PsReportTableClasses.stickyFirstHead;
|
|
45
|
+
if (isHeaderSticky)
|
|
46
|
+
return PsReportTableClasses.stickyHead;
|
|
47
|
+
if (isPinnedFirst)
|
|
48
|
+
return PsReportTableClasses.stickyFirstBody;
|
|
49
|
+
return '';
|
|
50
|
+
}
|
|
51
|
+
static cellClass(column, index, density, tone, isFirstColumnSticky) {
|
|
52
|
+
const isPinnedFirst = index === 0 && isFirstColumnSticky;
|
|
53
|
+
return [
|
|
54
|
+
PsReportTableClasses.cell[density],
|
|
55
|
+
PsReportTableClasses.align[PsReportTableService.alignOf(column)],
|
|
56
|
+
PsReportTableClasses.tone[tone],
|
|
57
|
+
column.wrap === true ? '' : PsReportTableClasses.nowrap,
|
|
58
|
+
column.maxWidth !== undefined ? PsReportTableClasses.truncate : '',
|
|
59
|
+
isPinnedFirst ? `${PsReportTableClasses.stickyFirstBody} ${PsTablePinClasses.edge}` : '',
|
|
60
|
+
]
|
|
61
|
+
.filter((name) => name !== '')
|
|
62
|
+
.join(' ');
|
|
63
|
+
}
|
|
64
|
+
static alignOf(column) {
|
|
65
|
+
return column.align !== undefined ? column.align : PsReportColumnAlign.left;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
+
import { PsTableStickyConfig } from '../constants/ps-table-sticky-config';
|
|
1
2
|
export class PsTableStickyHeadService {
|
|
2
3
|
static offset(pinnedBottom, tableTop, tableHeight, headHeight) {
|
|
3
4
|
return Math.min(Math.max(pinnedBottom - tableTop, 0), Math.max(tableHeight - headHeight, 0));
|
|
4
5
|
}
|
|
6
|
+
static sameInputs(previous, next) {
|
|
7
|
+
if (previous === null)
|
|
8
|
+
return false;
|
|
9
|
+
return (PsTableStickyHeadService.close(previous.headPin, next.headPin) &&
|
|
10
|
+
PsTableStickyHeadService.close(previous.headTravel, next.headTravel) &&
|
|
11
|
+
PsTableStickyHeadService.close(previous.cardPin, next.cardPin) &&
|
|
12
|
+
PsTableStickyHeadService.close(previous.cardTravel, next.cardTravel) &&
|
|
13
|
+
PsTableStickyHeadService.close(previous.scrollRange, next.scrollRange));
|
|
14
|
+
}
|
|
5
15
|
static keyframes(pinScroll, maxShift, scrollRange) {
|
|
6
16
|
if (scrollRange <= 0)
|
|
7
17
|
return [];
|
|
@@ -11,6 +21,9 @@ export class PsTableStickyHeadService {
|
|
|
11
21
|
shift: shiftAt(scroll),
|
|
12
22
|
}));
|
|
13
23
|
}
|
|
24
|
+
static close(first, second) {
|
|
25
|
+
return Math.abs(first - second) <= PsTableStickyConfig.inputTolerancePx;
|
|
26
|
+
}
|
|
14
27
|
static stops(scrolls, scrollRange) {
|
|
15
28
|
const inside = scrolls.filter((scroll) => scroll >= 0 && scroll <= scrollRange);
|
|
16
29
|
return inside.filter((scroll, index) => inside.indexOf(scroll) === index);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { PsStickyHeadRefs } from '../interfaces/ps-sticky-head-refs';
|
|
2
|
-
export declare const usePsStickyHead: ({ cardRef, contentRef, headRef, layoutKey, regionRef,
|
|
2
|
+
export declare const usePsStickyHead: ({ cardRef, contentRef, headRef, layoutKey, regionRef, stickyTop, }: PsStickyHeadRefs) => void;
|
|
@@ -5,18 +5,15 @@ const react_1 = require("react");
|
|
|
5
5
|
const ps_table_sticky_config_1 = require("../constants/ps-table-sticky-config");
|
|
6
6
|
const ps_table_scroll_service_1 = require("../services/ps-table-scroll-service");
|
|
7
7
|
const ps_table_sticky_head_service_1 = require("../services/ps-table-sticky-head-service");
|
|
8
|
-
const usePsStickyHead = ({ cardRef, contentRef, headRef, layoutKey, regionRef,
|
|
9
|
-
const [isStuck, setIsStuck] = (0, react_1.useState)(false);
|
|
8
|
+
const usePsStickyHead = ({ cardRef, contentRef, headRef, layoutKey, regionRef, stickyTop, }) => {
|
|
10
9
|
(0, react_1.useLayoutEffect)(() => {
|
|
11
10
|
const region = regionRef.current;
|
|
12
|
-
const sentinel = sentinelRef.current;
|
|
13
11
|
const card = cardRef.current;
|
|
14
12
|
const content = contentRef.current;
|
|
15
13
|
const head = headRef.current;
|
|
16
14
|
const table = head === null ? null : head.parentElement;
|
|
17
15
|
if (stickyTop === undefined ||
|
|
18
16
|
region === null ||
|
|
19
|
-
sentinel === null ||
|
|
20
17
|
card === null ||
|
|
21
18
|
content === null ||
|
|
22
19
|
head === null ||
|
|
@@ -26,6 +23,7 @@ const usePsStickyHead = ({ cardRef, contentRef, headRef, layoutKey, regionRef, s
|
|
|
26
23
|
const Timeline = window.ScrollTimeline;
|
|
27
24
|
const isDriven = scroller !== null && Timeline !== undefined;
|
|
28
25
|
let animations = [];
|
|
26
|
+
let measured = null;
|
|
29
27
|
let frame = 0;
|
|
30
28
|
const headTravel = () => Math.max(table.offsetHeight - head.offsetHeight, 0);
|
|
31
29
|
const drive = () => {
|
|
@@ -35,10 +33,19 @@ const usePsStickyHead = ({ cardRef, contentRef, headRef, layoutKey, regionRef, s
|
|
|
35
33
|
Number.parseFloat(getComputedStyle(region).top) +
|
|
36
34
|
region.offsetHeight +
|
|
37
35
|
ps_table_sticky_config_1.PsTableStickyConfig.cardGapPx;
|
|
38
|
-
const
|
|
36
|
+
const inputs = {
|
|
37
|
+
cardPin: content.getBoundingClientRect().top + scroller.scrollTop - pinnedLine,
|
|
38
|
+
cardTravel: card.offsetHeight,
|
|
39
|
+
headPin: table.getBoundingClientRect().top + scroller.scrollTop - pinnedLine,
|
|
40
|
+
headTravel: headTravel(),
|
|
41
|
+
scrollRange: scroller.scrollHeight - scroller.clientHeight,
|
|
42
|
+
};
|
|
43
|
+
if (ps_table_sticky_head_service_1.PsTableStickyHeadService.sameInputs(measured, inputs))
|
|
44
|
+
return;
|
|
45
|
+
measured = inputs;
|
|
39
46
|
const timeline = new Timeline({ axis: 'block', source: scroller });
|
|
40
|
-
const headFrames = ps_table_sticky_head_service_1.PsTableStickyHeadService.keyframes(
|
|
41
|
-
const cardFrames = ps_table_sticky_head_service_1.PsTableStickyHeadService.keyframes(
|
|
47
|
+
const headFrames = ps_table_sticky_head_service_1.PsTableStickyHeadService.keyframes(inputs.headPin, inputs.headTravel, inputs.scrollRange);
|
|
48
|
+
const cardFrames = ps_table_sticky_head_service_1.PsTableStickyHeadService.keyframes(inputs.cardPin, inputs.cardTravel, inputs.scrollRange);
|
|
42
49
|
animations.forEach((animation) => animation.cancel());
|
|
43
50
|
animations = [
|
|
44
51
|
head.animate(headFrames.map((keyframe) => ({
|
|
@@ -56,26 +63,22 @@ const usePsStickyHead = ({ cardRef, contentRef, headRef, layoutKey, regionRef, s
|
|
|
56
63
|
];
|
|
57
64
|
};
|
|
58
65
|
const follow = () => {
|
|
66
|
+
frame = 0;
|
|
59
67
|
const pinnedLine = region.getBoundingClientRect().bottom + ps_table_sticky_config_1.PsTableStickyConfig.cardGapPx;
|
|
60
68
|
head.style.transform = `translateY(${ps_table_sticky_head_service_1.PsTableStickyHeadService.offset(pinnedLine, table.getBoundingClientRect().top, table.offsetHeight, head.offsetHeight)}px)`;
|
|
61
69
|
const cut = ps_table_sticky_head_service_1.PsTableStickyHeadService.offset(pinnedLine, content.getBoundingClientRect().top, card.offsetHeight, 0);
|
|
62
70
|
card.style.transform = `translateY(${cut}px)`;
|
|
63
71
|
content.style.transform = `translateY(${-cut}px)`;
|
|
64
72
|
};
|
|
65
|
-
const check = () => {
|
|
66
|
-
frame = 0;
|
|
67
|
-
setIsStuck(sentinel.getBoundingClientRect().top < region.getBoundingClientRect().top - 1);
|
|
68
|
-
if (!isDriven)
|
|
69
|
-
follow();
|
|
70
|
-
};
|
|
71
73
|
const schedule = () => {
|
|
72
74
|
if (frame === 0)
|
|
73
|
-
frame = window.requestAnimationFrame(
|
|
75
|
+
frame = window.requestAnimationFrame(follow);
|
|
74
76
|
};
|
|
75
77
|
const measure = () => {
|
|
76
78
|
if (isDriven)
|
|
77
79
|
drive();
|
|
78
|
-
|
|
80
|
+
else
|
|
81
|
+
schedule();
|
|
79
82
|
};
|
|
80
83
|
const observer = new ResizeObserver(measure);
|
|
81
84
|
measure();
|
|
@@ -83,8 +86,9 @@ const usePsStickyHead = ({ cardRef, contentRef, headRef, layoutKey, regionRef, s
|
|
|
83
86
|
observer.observe(card);
|
|
84
87
|
if (scroller !== null)
|
|
85
88
|
Array.from(scroller.children).forEach((child) => observer.observe(child));
|
|
86
|
-
window.addEventListener('scroll', schedule, { capture: true, passive: true });
|
|
87
89
|
window.addEventListener('resize', measure);
|
|
90
|
+
if (!isDriven)
|
|
91
|
+
window.addEventListener('scroll', schedule, { capture: true, passive: true });
|
|
88
92
|
return () => {
|
|
89
93
|
observer.disconnect();
|
|
90
94
|
animations.forEach((animation) => animation.cancel());
|
|
@@ -96,7 +100,6 @@ const usePsStickyHead = ({ cardRef, contentRef, headRef, layoutKey, regionRef, s
|
|
|
96
100
|
if (frame !== 0)
|
|
97
101
|
window.cancelAnimationFrame(frame);
|
|
98
102
|
};
|
|
99
|
-
}, [cardRef, contentRef, headRef, layoutKey, regionRef,
|
|
100
|
-
return isStuck;
|
|
103
|
+
}, [cardRef, contentRef, headRef, layoutKey, regionRef, stickyTop]);
|
|
101
104
|
};
|
|
102
105
|
exports.usePsStickyHead = usePsStickyHead;
|
package/dist/index.d.ts
CHANGED
|
@@ -64,3 +64,11 @@ export * from './interfaces/ps-server-rows-result';
|
|
|
64
64
|
export * from './interfaces/ps-table-cursor-paging';
|
|
65
65
|
export * from './interfaces/ps-table-select-all-matching';
|
|
66
66
|
export * from './services/ps-server-rows-service';
|
|
67
|
+
export * from './components/ps-report-table';
|
|
68
|
+
export * from './components/ps-report-table-skeleton';
|
|
69
|
+
export * from './constants/ps-report-column-align';
|
|
70
|
+
export * from './constants/ps-report-row-kind';
|
|
71
|
+
export * from './constants/ps-report-row-tone';
|
|
72
|
+
export * from './constants/ps-report-table-density';
|
|
73
|
+
export * from './interfaces/ps-report-column';
|
|
74
|
+
export * from './services/ps-report-table-service';
|
package/dist/index.js
CHANGED
|
@@ -80,3 +80,11 @@ __exportStar(require("./interfaces/ps-server-rows-result"), exports);
|
|
|
80
80
|
__exportStar(require("./interfaces/ps-table-cursor-paging"), exports);
|
|
81
81
|
__exportStar(require("./interfaces/ps-table-select-all-matching"), exports);
|
|
82
82
|
__exportStar(require("./services/ps-server-rows-service"), exports);
|
|
83
|
+
__exportStar(require("./components/ps-report-table"), exports);
|
|
84
|
+
__exportStar(require("./components/ps-report-table-skeleton"), exports);
|
|
85
|
+
__exportStar(require("./constants/ps-report-column-align"), exports);
|
|
86
|
+
__exportStar(require("./constants/ps-report-row-kind"), exports);
|
|
87
|
+
__exportStar(require("./constants/ps-report-row-tone"), exports);
|
|
88
|
+
__exportStar(require("./constants/ps-report-table-density"), exports);
|
|
89
|
+
__exportStar(require("./interfaces/ps-report-column"), exports);
|
|
90
|
+
__exportStar(require("./services/ps-report-table-service"), exports);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { PsReportColumnAlign } from '../constants/ps-report-column-align';
|
|
3
|
+
export interface PsReportColumn<RowData> {
|
|
4
|
+
align?: PsReportColumnAlign;
|
|
5
|
+
id: string;
|
|
6
|
+
label: ReactNode;
|
|
7
|
+
maxWidth?: string;
|
|
8
|
+
minWidth?: string;
|
|
9
|
+
render: (row: RowData) => ReactNode;
|
|
10
|
+
width?: string;
|
|
11
|
+
wrap?: boolean;
|
|
12
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CSSProperties } from 'react';
|
|
2
|
+
import { PsReportColumnAlign } from '../constants/ps-report-column-align';
|
|
3
|
+
import { PsReportRowTone } from '../constants/ps-report-row-tone';
|
|
4
|
+
import { PsReportTableDensity } from '../constants/ps-report-table-density';
|
|
5
|
+
import type { PsReportCellPlan } from '../interfaces/ps-report-cell-plan';
|
|
6
|
+
import type { PsReportColumn } from '../interfaces/ps-report-column';
|
|
7
|
+
export declare class PsReportTableService {
|
|
8
|
+
static cells<RowData>(columns: PsReportColumn<RowData>[], leadSpan: number): PsReportCellPlan<RowData>[];
|
|
9
|
+
static span(count: number, leadSpan: number): number;
|
|
10
|
+
static indent(level: number, density: PsReportTableDensity): CSSProperties;
|
|
11
|
+
static columnStyle<RowData>(column: PsReportColumn<RowData>): CSSProperties;
|
|
12
|
+
static levelOf(level: number | undefined): number;
|
|
13
|
+
static headClass<RowData>(column: PsReportColumn<RowData>, index: number, density: PsReportTableDensity, isHeaderSticky: boolean, isFirstColumnSticky: boolean): string;
|
|
14
|
+
static headPin(isHeaderSticky: boolean, isPinnedFirst: boolean): string;
|
|
15
|
+
static cellClass<RowData>(column: PsReportColumn<RowData>, index: number, density: PsReportTableDensity, tone: PsReportRowTone, isFirstColumnSticky: boolean): string;
|
|
16
|
+
static alignOf<RowData>(column: PsReportColumn<RowData>): PsReportColumnAlign;
|
|
17
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsReportTableService = void 0;
|
|
4
|
+
const ps_report_column_align_1 = require("../constants/ps-report-column-align");
|
|
5
|
+
const ps_report_table_classes_1 = require("../constants/ps-report-table-classes");
|
|
6
|
+
const ps_report_table_config_1 = require("../constants/ps-report-table-config");
|
|
7
|
+
const ps_table_pin_classes_1 = require("../constants/ps-table-pin-classes");
|
|
8
|
+
class PsReportTableService {
|
|
9
|
+
static cells(columns, leadSpan) {
|
|
10
|
+
const span = PsReportTableService.span(columns.length, leadSpan);
|
|
11
|
+
const plan = [{ colSpan: span, column: columns[0], index: 0 }];
|
|
12
|
+
for (let index = span; index < columns.length; index += 1)
|
|
13
|
+
plan.push({ colSpan: 1, column: columns[index], index });
|
|
14
|
+
return plan;
|
|
15
|
+
}
|
|
16
|
+
static span(count, leadSpan) {
|
|
17
|
+
return Math.min(Math.max(leadSpan, 1), count);
|
|
18
|
+
}
|
|
19
|
+
static indent(level, density) {
|
|
20
|
+
const base = ps_report_table_config_1.PsReportTableConfig.baseIndentRem[density];
|
|
21
|
+
return { paddingLeft: `${base + level * ps_report_table_config_1.PsReportTableConfig.indentRem}rem` };
|
|
22
|
+
}
|
|
23
|
+
static columnStyle(column) {
|
|
24
|
+
return {
|
|
25
|
+
maxWidth: column.maxWidth,
|
|
26
|
+
minWidth: column.minWidth,
|
|
27
|
+
width: column.width,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
static levelOf(level) {
|
|
31
|
+
return level !== undefined && level > 0 ? level : 0;
|
|
32
|
+
}
|
|
33
|
+
static headClass(column, index, density, isHeaderSticky, isFirstColumnSticky) {
|
|
34
|
+
const isPinnedFirst = index === 0 && isFirstColumnSticky;
|
|
35
|
+
const pin = PsReportTableService.headPin(isHeaderSticky, isPinnedFirst);
|
|
36
|
+
return [
|
|
37
|
+
ps_report_table_classes_1.PsReportTableClasses.headCell[density],
|
|
38
|
+
ps_report_table_classes_1.PsReportTableClasses.align[PsReportTableService.alignOf(column)],
|
|
39
|
+
pin,
|
|
40
|
+
isPinnedFirst ? ps_table_pin_classes_1.PsTablePinClasses.edge : '',
|
|
41
|
+
]
|
|
42
|
+
.filter((name) => name !== '')
|
|
43
|
+
.join(' ');
|
|
44
|
+
}
|
|
45
|
+
static headPin(isHeaderSticky, isPinnedFirst) {
|
|
46
|
+
if (isHeaderSticky && isPinnedFirst)
|
|
47
|
+
return ps_report_table_classes_1.PsReportTableClasses.stickyFirstHead;
|
|
48
|
+
if (isHeaderSticky)
|
|
49
|
+
return ps_report_table_classes_1.PsReportTableClasses.stickyHead;
|
|
50
|
+
if (isPinnedFirst)
|
|
51
|
+
return ps_report_table_classes_1.PsReportTableClasses.stickyFirstBody;
|
|
52
|
+
return '';
|
|
53
|
+
}
|
|
54
|
+
static cellClass(column, index, density, tone, isFirstColumnSticky) {
|
|
55
|
+
const isPinnedFirst = index === 0 && isFirstColumnSticky;
|
|
56
|
+
return [
|
|
57
|
+
ps_report_table_classes_1.PsReportTableClasses.cell[density],
|
|
58
|
+
ps_report_table_classes_1.PsReportTableClasses.align[PsReportTableService.alignOf(column)],
|
|
59
|
+
ps_report_table_classes_1.PsReportTableClasses.tone[tone],
|
|
60
|
+
column.wrap === true ? '' : ps_report_table_classes_1.PsReportTableClasses.nowrap,
|
|
61
|
+
column.maxWidth !== undefined ? ps_report_table_classes_1.PsReportTableClasses.truncate : '',
|
|
62
|
+
isPinnedFirst ? `${ps_report_table_classes_1.PsReportTableClasses.stickyFirstBody} ${ps_table_pin_classes_1.PsTablePinClasses.edge}` : '',
|
|
63
|
+
]
|
|
64
|
+
.filter((name) => name !== '')
|
|
65
|
+
.join(' ');
|
|
66
|
+
}
|
|
67
|
+
static alignOf(column) {
|
|
68
|
+
return column.align !== undefined ? column.align : ps_report_column_align_1.PsReportColumnAlign.left;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.PsReportTableService = PsReportTableService;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import type { PsTableStickyHeadInputs } from '../interfaces/ps-table-sticky-head-inputs';
|
|
1
2
|
import type { PsTableStickyHeadKeyframe } from '../interfaces/ps-table-sticky-head-keyframe';
|
|
2
3
|
export declare class PsTableStickyHeadService {
|
|
3
4
|
static offset(pinnedBottom: number, tableTop: number, tableHeight: number, headHeight: number): number;
|
|
5
|
+
static sameInputs(previous: PsTableStickyHeadInputs | null, next: PsTableStickyHeadInputs): boolean;
|
|
4
6
|
static keyframes(pinScroll: number, maxShift: number, scrollRange: number): PsTableStickyHeadKeyframe[];
|
|
7
|
+
private static close;
|
|
5
8
|
private static stops;
|
|
6
9
|
}
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PsTableStickyHeadService = void 0;
|
|
4
|
+
const ps_table_sticky_config_1 = require("../constants/ps-table-sticky-config");
|
|
4
5
|
class PsTableStickyHeadService {
|
|
5
6
|
static offset(pinnedBottom, tableTop, tableHeight, headHeight) {
|
|
6
7
|
return Math.min(Math.max(pinnedBottom - tableTop, 0), Math.max(tableHeight - headHeight, 0));
|
|
7
8
|
}
|
|
9
|
+
static sameInputs(previous, next) {
|
|
10
|
+
if (previous === null)
|
|
11
|
+
return false;
|
|
12
|
+
return (PsTableStickyHeadService.close(previous.headPin, next.headPin) &&
|
|
13
|
+
PsTableStickyHeadService.close(previous.headTravel, next.headTravel) &&
|
|
14
|
+
PsTableStickyHeadService.close(previous.cardPin, next.cardPin) &&
|
|
15
|
+
PsTableStickyHeadService.close(previous.cardTravel, next.cardTravel) &&
|
|
16
|
+
PsTableStickyHeadService.close(previous.scrollRange, next.scrollRange));
|
|
17
|
+
}
|
|
8
18
|
static keyframes(pinScroll, maxShift, scrollRange) {
|
|
9
19
|
if (scrollRange <= 0)
|
|
10
20
|
return [];
|
|
@@ -14,6 +24,9 @@ class PsTableStickyHeadService {
|
|
|
14
24
|
shift: shiftAt(scroll),
|
|
15
25
|
}));
|
|
16
26
|
}
|
|
27
|
+
static close(first, second) {
|
|
28
|
+
return Math.abs(first - second) <= ps_table_sticky_config_1.PsTableStickyConfig.inputTolerancePx;
|
|
29
|
+
}
|
|
17
30
|
static stops(scrolls, scrollRange) {
|
|
18
31
|
const inside = scrolls.filter((scroll) => scroll >= 0 && scroll <= scrollRange);
|
|
19
32
|
return inside.filter((scroll, index) => inside.indexOf(scroll) === index);
|