beautiful-grid 1.0.0-rc.1
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/LICENSE +202 -0
- package/NOTICE +6 -0
- package/README.md +977 -0
- package/TRADEMARK.md +17 -0
- package/cjs/BGrid.js +503 -0
- package/cjs/components/CellEditorIcon.js +209 -0
- package/cjs/components/CellNavigationDomSync.js +117 -0
- package/cjs/components/CellTextEditorGateway.js +393 -0
- package/cjs/components/ColResizer.js +144 -0
- package/cjs/components/EditorPortalRoot.js +96 -0
- package/cjs/components/GridOptionalSurfaces.js +47 -0
- package/cjs/components/GripVertical.js +48 -0
- package/cjs/components/Loading.js +76 -0
- package/cjs/components/Pagination.js +93 -0
- package/cjs/components/PluginCellEditor.js +258 -0
- package/cjs/components/RowSelector.js +74 -0
- package/cjs/components/Table.js +2572 -0
- package/cjs/components/TableBody.js +446 -0
- package/cjs/components/TableBodyCell.js +112 -0
- package/cjs/components/TableBodyFrozen.js +44 -0
- package/cjs/components/TableColGroup.js +48 -0
- package/cjs/components/TableColGroupFrozen.js +57 -0
- package/cjs/components/TableFooter.js +70 -0
- package/cjs/components/TableHead.js +195 -0
- package/cjs/components/TableHeadColumn.js +124 -0
- package/cjs/components/TableHeadFrozen.js +165 -0
- package/cjs/components/TableSummary.js +133 -0
- package/cjs/components/TableSummaryFronzen.js +105 -0
- package/cjs/components/columnSortableRuntime.js +46 -0
- package/cjs/components/context-menu/GridContextMenu.js +174 -0
- package/cjs/components/context-menu/index.js +17 -0
- package/cjs/components/scrollbar/CustomScrollbar.js +58 -0
- package/cjs/components/scrollbar/ScrollbarButton.js +69 -0
- package/cjs/components/scrollbar/ScrollbarTrack.js +106 -0
- package/cjs/components/scrollbar/index.js +20 -0
- package/cjs/components/scrollbar/useScrollbarMetrics.js +103 -0
- package/cjs/components/search/GridSearchController.js +170 -0
- package/cjs/components/search/GridSearchPopover.js +163 -0
- package/cjs/components/search/index.js +18 -0
- package/cjs/components/selection/CellSelectionOverlay.js +52 -0
- package/cjs/components/selection/CellSelectionOverlayLayer.js +65 -0
- package/cjs/components/selection/index.js +18 -0
- package/cjs/components/toolbox/TableHeadToolbox.js +308 -0
- package/cjs/components/toolbox/ToolboxCustomSection.js +55 -0
- package/cjs/components/toolbox/ToolboxNumberFilterSection.js +151 -0
- package/cjs/components/toolbox/ToolboxSortSection.js +68 -0
- package/cjs/components/toolbox/ToolboxTextFilterSection.js +114 -0
- package/cjs/components/toolbox/ToolboxValueFilterSection.js +250 -0
- package/cjs/components/toolbox/index.js +22 -0
- package/cjs/components/useColumnSortable.js +70 -0
- package/cjs/editors/createDateEditorPlugin.js +88 -0
- package/cjs/editors/createSelectEditorPlugin.js +98 -0
- package/cjs/editors/defineEditorPlugin.js +17 -0
- package/cjs/editors/index.js +19 -0
- package/cjs/index.js +19 -0
- package/cjs/store/createAppStore.js +1645 -0
- package/cjs/store/index.js +17 -0
- package/cjs/types.js +14 -0
- package/cjs/utils/buildHeaderMatrix.js +265 -0
- package/cjs/utils/cellEditState.js +71 -0
- package/cjs/utils/cellEditTransaction.js +138 -0
- package/cjs/utils/cellSelectionGeometry.js +179 -0
- package/cjs/utils/common.js +154 -0
- package/cjs/utils/coordinate.js +125 -0
- package/cjs/utils/createPivotData.js +271 -0
- package/cjs/utils/delay.js +7 -0
- package/cjs/utils/filterData.js +182 -0
- package/cjs/utils/getCellSelectionAxisState.js +39 -0
- package/cjs/utils/getCellValue.js +21 -0
- package/cjs/utils/getColumnId.js +60 -0
- package/cjs/utils/getFrozenColumnsWidth.js +21 -0
- package/cjs/utils/getLineNumber.js +7 -0
- package/cjs/utils/getVisibleScrollableRowRange.js +24 -0
- package/cjs/utils/gridSearch.js +135 -0
- package/cjs/utils/index.js +39 -0
- package/cjs/utils/mergedCells.js +76 -0
- package/cjs/utils/mouseEventSubscribe.js +119 -0
- package/cjs/utils/number/index.js +19 -0
- package/cjs/utils/number/toFixed.js +6 -0
- package/cjs/utils/number/toMoney.js +13 -0
- package/cjs/utils/number/toNumber.js +12 -0
- package/cjs/utils/processDataQuery.js +126 -0
- package/cjs/utils/rowReorder.js +131 -0
- package/cjs/utils/scrollbar.js +62 -0
- package/cjs/utils/updateDataQuery.js +147 -0
- package/cjs/utils/useBodyData.js +277 -0
- package/cjs/utils/useForceUpdate.js +57 -0
- package/cjs/utils/useRowReorderController.js +666 -0
- package/esm/BGrid.js +466 -0
- package/esm/components/CellEditorIcon.js +115 -0
- package/esm/components/CellNavigationDomSync.js +80 -0
- package/esm/components/CellTextEditorGateway.js +275 -0
- package/esm/components/ColResizer.js +60 -0
- package/esm/components/EditorPortalRoot.js +57 -0
- package/esm/components/GridOptionalSurfaces.js +10 -0
- package/esm/components/GripVertical.js +11 -0
- package/esm/components/Loading.js +24 -0
- package/esm/components/Pagination.js +44 -0
- package/esm/components/PluginCellEditor.js +110 -0
- package/esm/components/RowSelector.js +38 -0
- package/esm/components/Table.js +2347 -0
- package/esm/components/TableBody.js +315 -0
- package/esm/components/TableBodyCell.js +73 -0
- package/esm/components/TableBodyFrozen.js +6 -0
- package/esm/components/TableColGroup.js +10 -0
- package/esm/components/TableColGroupFrozen.js +19 -0
- package/esm/components/TableFooter.js +30 -0
- package/esm/components/TableHead.js +114 -0
- package/esm/components/TableHeadColumn.js +86 -0
- package/esm/components/TableHeadFrozen.js +102 -0
- package/esm/components/TableSummary.js +66 -0
- package/esm/components/TableSummaryFronzen.js +62 -0
- package/esm/components/columnSortableRuntime.js +38 -0
- package/esm/components/context-menu/GridContextMenu.js +115 -0
- package/esm/components/context-menu/index.js +1 -0
- package/esm/components/scrollbar/CustomScrollbar.js +21 -0
- package/esm/components/scrollbar/ScrollbarButton.js +32 -0
- package/esm/components/scrollbar/ScrollbarTrack.js +66 -0
- package/esm/components/scrollbar/index.js +4 -0
- package/esm/components/scrollbar/useScrollbarMetrics.js +74 -0
- package/esm/components/search/GridSearchController.js +98 -0
- package/esm/components/search/GridSearchPopover.js +109 -0
- package/esm/components/search/index.js +2 -0
- package/esm/components/selection/CellSelectionOverlay.js +5 -0
- package/esm/components/selection/CellSelectionOverlayLayer.js +28 -0
- package/esm/components/selection/index.js +2 -0
- package/esm/components/toolbox/TableHeadToolbox.js +223 -0
- package/esm/components/toolbox/ToolboxCustomSection.js +18 -0
- package/esm/components/toolbox/ToolboxNumberFilterSection.js +98 -0
- package/esm/components/toolbox/ToolboxSortSection.js +31 -0
- package/esm/components/toolbox/ToolboxTextFilterSection.js +61 -0
- package/esm/components/toolbox/ToolboxValueFilterSection.js +195 -0
- package/esm/components/toolbox/index.js +6 -0
- package/esm/components/useColumnSortable.js +33 -0
- package/esm/editors/createDateEditorPlugin.js +48 -0
- package/esm/editors/createSelectEditorPlugin.js +60 -0
- package/esm/editors/defineEditorPlugin.js +6 -0
- package/esm/editors/index.js +3 -0
- package/esm/index.js +3 -0
- package/esm/store/createAppStore.js +1483 -0
- package/esm/store/index.js +1 -0
- package/esm/types.js +11 -0
- package/esm/utils/buildHeaderMatrix.js +231 -0
- package/esm/utils/cellEditState.js +32 -0
- package/esm/utils/cellEditTransaction.js +96 -0
- package/esm/utils/cellSelectionGeometry.js +166 -0
- package/esm/utils/common.js +145 -0
- package/esm/utils/coordinate.js +112 -0
- package/esm/utils/createPivotData.js +226 -0
- package/esm/utils/delay.js +1 -0
- package/esm/utils/filterData.js +176 -0
- package/esm/utils/getCellSelectionAxisState.js +34 -0
- package/esm/utils/getCellValue.js +18 -0
- package/esm/utils/getColumnId.js +52 -0
- package/esm/utils/getFrozenColumnsWidth.js +16 -0
- package/esm/utils/getLineNumber.js +3 -0
- package/esm/utils/getVisibleScrollableRowRange.js +20 -0
- package/esm/utils/gridSearch.js +127 -0
- package/esm/utils/index.js +23 -0
- package/esm/utils/mergedCells.js +70 -0
- package/esm/utils/mouseEventSubscribe.js +113 -0
- package/esm/utils/number/index.js +3 -0
- package/esm/utils/number/toFixed.js +3 -0
- package/esm/utils/number/toMoney.js +10 -0
- package/esm/utils/number/toNumber.js +9 -0
- package/esm/utils/processDataQuery.js +119 -0
- package/esm/utils/rowReorder.js +85 -0
- package/esm/utils/scrollbar.js +51 -0
- package/esm/utils/updateDataQuery.js +130 -0
- package/esm/utils/useBodyData.js +153 -0
- package/esm/utils/useForceUpdate.js +5 -0
- package/esm/utils/useRowReorderController.js +603 -0
- package/package.json +54 -0
- package/style.css +2508 -0
- package/types/BGrid.d.ts +3 -0
- package/types/components/CellEditorIcon.d.ts +13 -0
- package/types/components/CellNavigationDomSync.d.ts +17 -0
- package/types/components/CellTextEditorGateway.d.ts +20 -0
- package/types/components/ColResizer.d.ts +12 -0
- package/types/components/EditorPortalRoot.d.ts +8 -0
- package/types/components/GridOptionalSurfaces.d.ts +10 -0
- package/types/components/GripVertical.d.ts +6 -0
- package/types/components/Loading.d.ts +7 -0
- package/types/components/Pagination.d.ts +5 -0
- package/types/components/PluginCellEditor.d.ts +13 -0
- package/types/components/RowSelector.d.ts +10 -0
- package/types/components/Table.d.ts +61 -0
- package/types/components/TableBody.d.ts +39 -0
- package/types/components/TableBodyCell.d.ts +20 -0
- package/types/components/TableBodyFrozen.d.ts +15 -0
- package/types/components/TableColGroup.d.ts +3 -0
- package/types/components/TableColGroupFrozen.d.ts +5 -0
- package/types/components/TableFooter.d.ts +9 -0
- package/types/components/TableHead.d.ts +21 -0
- package/types/components/TableHeadColumn.d.ts +8 -0
- package/types/components/TableHeadFrozen.d.ts +7 -0
- package/types/components/TableSummary.d.ts +13 -0
- package/types/components/TableSummaryFronzen.d.ts +7 -0
- package/types/components/columnSortableRuntime.d.ts +12 -0
- package/types/components/context-menu/GridContextMenu.d.ts +6 -0
- package/types/components/context-menu/index.d.ts +1 -0
- package/types/components/scrollbar/CustomScrollbar.d.ts +11 -0
- package/types/components/scrollbar/ScrollbarButton.d.ts +9 -0
- package/types/components/scrollbar/ScrollbarTrack.d.ts +11 -0
- package/types/components/scrollbar/index.d.ts +4 -0
- package/types/components/scrollbar/useScrollbarMetrics.d.ts +12 -0
- package/types/components/search/GridSearchController.d.ts +1 -0
- package/types/components/search/GridSearchPopover.d.ts +6 -0
- package/types/components/search/index.d.ts +2 -0
- package/types/components/selection/CellSelectionOverlay.d.ts +17 -0
- package/types/components/selection/CellSelectionOverlayLayer.d.ts +18 -0
- package/types/components/selection/index.d.ts +2 -0
- package/types/components/toolbox/TableHeadToolbox.d.ts +13 -0
- package/types/components/toolbox/ToolboxCustomSection.d.ts +11 -0
- package/types/components/toolbox/ToolboxNumberFilterSection.d.ts +8 -0
- package/types/components/toolbox/ToolboxSortSection.d.ts +8 -0
- package/types/components/toolbox/ToolboxTextFilterSection.d.ts +8 -0
- package/types/components/toolbox/ToolboxValueFilterSection.d.ts +8 -0
- package/types/components/toolbox/index.d.ts +6 -0
- package/types/components/useColumnSortable.d.ts +13 -0
- package/types/editors/createDateEditorPlugin.d.ts +8 -0
- package/types/editors/createSelectEditorPlugin.d.ts +15 -0
- package/types/editors/defineEditorPlugin.d.ts +2 -0
- package/types/editors/index.d.ts +3 -0
- package/types/index.d.ts +3 -0
- package/types/store/createAppStore.d.ts +13 -0
- package/types/store/index.d.ts +1 -0
- package/types/types.d.ts +864 -0
- package/types/utils/buildHeaderMatrix.d.ts +32 -0
- package/types/utils/cellEditState.d.ts +12 -0
- package/types/utils/cellEditTransaction.d.ts +14 -0
- package/types/utils/cellSelectionGeometry.d.ts +34 -0
- package/types/utils/common.d.ts +3 -0
- package/types/utils/coordinate.d.ts +29 -0
- package/types/utils/createPivotData.d.ts +12 -0
- package/types/utils/delay.d.ts +1 -0
- package/types/utils/filterData.d.ts +18 -0
- package/types/utils/getCellSelectionAxisState.d.ts +12 -0
- package/types/utils/getCellValue.d.ts +2 -0
- package/types/utils/getColumnId.d.ts +19 -0
- package/types/utils/getFrozenColumnsWidth.d.ts +12 -0
- package/types/utils/getLineNumber.d.ts +6 -0
- package/types/utils/getVisibleScrollableRowRange.d.ts +20 -0
- package/types/utils/gridSearch.d.ts +18 -0
- package/types/utils/index.d.ts +23 -0
- package/types/utils/mergedCells.d.ts +14 -0
- package/types/utils/mouseEventSubscribe.d.ts +18 -0
- package/types/utils/number/index.d.ts +3 -0
- package/types/utils/number/toFixed.d.ts +1 -0
- package/types/utils/number/toMoney.d.ts +1 -0
- package/types/utils/number/toNumber.d.ts +1 -0
- package/types/utils/processDataQuery.d.ts +19 -0
- package/types/utils/rowReorder.d.ts +24 -0
- package/types/utils/scrollbar.d.ts +13 -0
- package/types/utils/updateDataQuery.d.ts +28 -0
- package/types/utils/useBodyData.d.ts +9 -0
- package/types/utils/useForceUpdate.d.ts +1 -0
- package/types/utils/useRowReorderController.d.ts +19 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { getCellValueByRowKey } from './getCellValue';
|
|
2
|
+
import { resolveLogicalCell } from './mergedCells';
|
|
3
|
+
export function normalizeSearchText(value) {
|
|
4
|
+
if (value === null || value === undefined)
|
|
5
|
+
return '';
|
|
6
|
+
if (typeof value === 'string')
|
|
7
|
+
return value.normalize('NFC');
|
|
8
|
+
if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {
|
|
9
|
+
return String(value).normalize('NFC');
|
|
10
|
+
}
|
|
11
|
+
if (value instanceof Date) {
|
|
12
|
+
try {
|
|
13
|
+
return value.toISOString().normalize('NFC');
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return String(value).normalize('NFC');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const stringified = JSON.stringify(value);
|
|
21
|
+
return (stringified ?? String(value)).normalize('NFC');
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
try {
|
|
25
|
+
return String(value).normalize('NFC');
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return '';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function getRowKey(rowKey, item) {
|
|
33
|
+
return rowKey ? getCellValueByRowKey(rowKey, item.values) : undefined;
|
|
34
|
+
}
|
|
35
|
+
function isPromiseLike(value) {
|
|
36
|
+
return !!value && (typeof value === 'object' || typeof value === 'function') && 'then' in value;
|
|
37
|
+
}
|
|
38
|
+
export function findGridSearchMatches({ data, columns, sourceIndexByVisibleIndex, rowKey, cellMergeOptions, searchOptions, query, startRowIndex = 0, endRowIndex = data.length, onGetSearchTextError, }) {
|
|
39
|
+
const normalizedQuery = normalizeSearchText(query).toLowerCase();
|
|
40
|
+
if (normalizedQuery.length === 0 || data.length === 0 || columns.length === 0)
|
|
41
|
+
return [];
|
|
42
|
+
const matches = [];
|
|
43
|
+
const seenLogicalCells = new Set();
|
|
44
|
+
const safeStart = Math.max(0, Math.floor(startRowIndex));
|
|
45
|
+
const safeEnd = Math.min(data.length, Math.max(safeStart, Math.floor(endRowIndex)));
|
|
46
|
+
for (let visibleIndex = safeStart; visibleIndex < safeEnd; visibleIndex += 1) {
|
|
47
|
+
for (let columnIndex = 0; columnIndex < columns.length; columnIndex += 1) {
|
|
48
|
+
const column = columns[columnIndex];
|
|
49
|
+
if (!column || column.searchable === false)
|
|
50
|
+
continue;
|
|
51
|
+
const logical = resolveLogicalCell(data, cellMergeOptions, { rowIndex: visibleIndex, columnIndex });
|
|
52
|
+
const logicalToken = `${logical.cell.rowIndex}:${logical.cell.columnIndex}`;
|
|
53
|
+
if (seenLogicalCells.has(logicalToken))
|
|
54
|
+
continue;
|
|
55
|
+
seenLogicalCells.add(logicalToken);
|
|
56
|
+
const canonicalVisibleIndex = logical.cell.rowIndex;
|
|
57
|
+
const item = data[canonicalVisibleIndex];
|
|
58
|
+
if (!item)
|
|
59
|
+
continue;
|
|
60
|
+
const sourceIndex = sourceIndexByVisibleIndex[canonicalVisibleIndex] ?? canonicalVisibleIndex;
|
|
61
|
+
const value = getCellValueByRowKey(column.key, item.values);
|
|
62
|
+
const params = {
|
|
63
|
+
cell: logical.cell,
|
|
64
|
+
visibleIndex: canonicalVisibleIndex,
|
|
65
|
+
sourceIndex,
|
|
66
|
+
rowKey: getRowKey(rowKey, item),
|
|
67
|
+
columnIndex,
|
|
68
|
+
columnId: column.columnId,
|
|
69
|
+
column,
|
|
70
|
+
item,
|
|
71
|
+
values: item.values,
|
|
72
|
+
value,
|
|
73
|
+
};
|
|
74
|
+
let searchableValue = value;
|
|
75
|
+
const getSearchText = column.getSearchText ?? searchOptions?.getSearchText;
|
|
76
|
+
if (getSearchText) {
|
|
77
|
+
try {
|
|
78
|
+
const resolved = getSearchText(params);
|
|
79
|
+
if (isPromiseLike(resolved)) {
|
|
80
|
+
throw new TypeError('getSearchText must return synchronously.');
|
|
81
|
+
}
|
|
82
|
+
searchableValue = resolved;
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
onGetSearchTextError?.(column.columnId, error);
|
|
86
|
+
searchableValue = value;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (!normalizeSearchText(searchableValue).toLowerCase().includes(normalizedQuery))
|
|
90
|
+
continue;
|
|
91
|
+
matches.push({
|
|
92
|
+
cell: logical.cell,
|
|
93
|
+
visibleIndex: canonicalVisibleIndex,
|
|
94
|
+
sourceIndex,
|
|
95
|
+
rowKey: params.rowKey,
|
|
96
|
+
columnIndex,
|
|
97
|
+
columnId: column.columnId,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return matches;
|
|
102
|
+
}
|
|
103
|
+
export function dedupeSearchMatches(matches) {
|
|
104
|
+
const seen = new Set();
|
|
105
|
+
return matches.filter(match => {
|
|
106
|
+
const token = `${match.cell.rowIndex}:${match.cell.columnIndex}`;
|
|
107
|
+
if (seen.has(token))
|
|
108
|
+
return false;
|
|
109
|
+
seen.add(token);
|
|
110
|
+
return true;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
export function findMatchingSearchResultIndex(matches, previous, previousIndex) {
|
|
114
|
+
if (matches.length === 0)
|
|
115
|
+
return undefined;
|
|
116
|
+
if (!previous)
|
|
117
|
+
return 0;
|
|
118
|
+
const rowKeyMatch = previous.rowKey !== undefined
|
|
119
|
+
? matches.findIndex(match => Object.is(match.rowKey, previous.rowKey) && match.columnId === previous.columnId)
|
|
120
|
+
: -1;
|
|
121
|
+
if (rowKeyMatch >= 0)
|
|
122
|
+
return rowKeyMatch;
|
|
123
|
+
const sourceMatch = matches.findIndex(match => match.sourceIndex === previous.sourceIndex && match.columnId === previous.columnId);
|
|
124
|
+
if (sourceMatch >= 0)
|
|
125
|
+
return sourceMatch;
|
|
126
|
+
return Math.min(Math.max(previousIndex ?? 0, 0), matches.length - 1);
|
|
127
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export * from './getCellValue';
|
|
2
|
+
export * from './getFrozenColumnsWidth';
|
|
3
|
+
export * from './mouseEventSubscribe';
|
|
4
|
+
export * from './common';
|
|
5
|
+
export * from './useForceUpdate';
|
|
6
|
+
export * from './delay';
|
|
7
|
+
export * from './getLineNumber';
|
|
8
|
+
export * from './useBodyData';
|
|
9
|
+
export * from './createPivotData';
|
|
10
|
+
export * from './getColumnId';
|
|
11
|
+
export * from './updateDataQuery';
|
|
12
|
+
export * from './filterData';
|
|
13
|
+
export * from './processDataQuery';
|
|
14
|
+
export * from './scrollbar';
|
|
15
|
+
export * from './number';
|
|
16
|
+
export * from './buildHeaderMatrix';
|
|
17
|
+
export * from './getVisibleScrollableRowRange';
|
|
18
|
+
export * from './cellEditState';
|
|
19
|
+
export * from './getCellSelectionAxisState';
|
|
20
|
+
export * from './mergedCells';
|
|
21
|
+
export * from './gridSearch';
|
|
22
|
+
export * from './cellEditTransaction';
|
|
23
|
+
export * from './rowReorder';
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { getCellValueByRowKey } from './getCellValue';
|
|
2
|
+
const mergedRowRangeCache = new WeakMap();
|
|
3
|
+
function getMergeCacheKey(mergeBy) {
|
|
4
|
+
return Array.isArray(mergeBy) ? `path:${JSON.stringify(mergeBy)}` : `key:${mergeBy}`;
|
|
5
|
+
}
|
|
6
|
+
export function getMergedRowRange(data, mergeBy, requestedRowIndex) {
|
|
7
|
+
if (data.length === 0)
|
|
8
|
+
return { startRowIndex: 0, endRowIndex: 0 };
|
|
9
|
+
const rowIndex = Math.min(Math.max(requestedRowIndex, 0), data.length - 1);
|
|
10
|
+
const cacheKey = getMergeCacheKey(mergeBy);
|
|
11
|
+
let cacheByColumn = mergedRowRangeCache.get(data);
|
|
12
|
+
if (!cacheByColumn) {
|
|
13
|
+
cacheByColumn = new Map();
|
|
14
|
+
mergedRowRangeCache.set(data, cacheByColumn);
|
|
15
|
+
}
|
|
16
|
+
let rangesByRow = cacheByColumn.get(cacheKey);
|
|
17
|
+
if (!rangesByRow) {
|
|
18
|
+
rangesByRow = new Map();
|
|
19
|
+
cacheByColumn.set(cacheKey, rangesByRow);
|
|
20
|
+
}
|
|
21
|
+
const cachedRange = rangesByRow.get(rowIndex);
|
|
22
|
+
if (cachedRange)
|
|
23
|
+
return cachedRange;
|
|
24
|
+
const value = getCellValueByRowKey(mergeBy, data[rowIndex].values);
|
|
25
|
+
let startRowIndex = rowIndex;
|
|
26
|
+
let endRowIndex = rowIndex;
|
|
27
|
+
while (startRowIndex > 0 && Object.is(getCellValueByRowKey(mergeBy, data[startRowIndex - 1].values), value)) {
|
|
28
|
+
startRowIndex -= 1;
|
|
29
|
+
}
|
|
30
|
+
while (endRowIndex < data.length - 1 &&
|
|
31
|
+
Object.is(getCellValueByRowKey(mergeBy, data[endRowIndex + 1].values), value)) {
|
|
32
|
+
endRowIndex += 1;
|
|
33
|
+
}
|
|
34
|
+
const range = { startRowIndex, endRowIndex };
|
|
35
|
+
for (let index = startRowIndex; index <= endRowIndex; index += 1) {
|
|
36
|
+
rangesByRow.set(index, range);
|
|
37
|
+
}
|
|
38
|
+
return range;
|
|
39
|
+
}
|
|
40
|
+
export function resolveLogicalCell(data, cellMergeOptions, requestedCell) {
|
|
41
|
+
if (data.length === 0) {
|
|
42
|
+
return {
|
|
43
|
+
cell: requestedCell,
|
|
44
|
+
rowRange: { startRowIndex: requestedCell.rowIndex, endRowIndex: requestedCell.rowIndex },
|
|
45
|
+
rowIndexes: [requestedCell.rowIndex],
|
|
46
|
+
merged: false,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const rowIndex = Math.min(Math.max(requestedCell.rowIndex, 0), data.length - 1);
|
|
50
|
+
const rule = cellMergeOptions?.columnsMap?.[requestedCell.columnIndex];
|
|
51
|
+
if (!rule) {
|
|
52
|
+
return {
|
|
53
|
+
cell: { rowIndex, columnIndex: requestedCell.columnIndex },
|
|
54
|
+
rowRange: { startRowIndex: rowIndex, endRowIndex: rowIndex },
|
|
55
|
+
rowIndexes: [rowIndex],
|
|
56
|
+
merged: false,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
const rowRange = getMergedRowRange(data, rule.mergeBy, rowIndex);
|
|
60
|
+
const rowIndexes = Array.from({ length: rowRange.endRowIndex - rowRange.startRowIndex + 1 }, (_, index) => rowRange.startRowIndex + index);
|
|
61
|
+
return {
|
|
62
|
+
cell: { rowIndex: rowRange.startRowIndex, columnIndex: requestedCell.columnIndex },
|
|
63
|
+
rowRange,
|
|
64
|
+
rowIndexes,
|
|
65
|
+
merged: rowIndexes.length > 1,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export function isRowInLogicalCell(logicalCell, rowIndex) {
|
|
69
|
+
return rowIndex >= logicalCell.rowRange.startRowIndex && rowIndex <= logicalCell.rowRange.endRowIndex;
|
|
70
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { throttle } from './common';
|
|
2
|
+
export const mouseEventSubscribe = (callBack, onEnd, options) => {
|
|
3
|
+
const { interval = 30, target, pointerId, initialClientX } = options || {};
|
|
4
|
+
const ownerDocument = target?.ownerDocument ?? document;
|
|
5
|
+
const ownerWindow = ownerDocument.defaultView ?? window;
|
|
6
|
+
const ownerBody = ownerDocument.body;
|
|
7
|
+
const canUsePointerCapture = typeof pointerId === 'number' && !!target?.setPointerCapture;
|
|
8
|
+
let ended = false;
|
|
9
|
+
let hasMoveEvent = false;
|
|
10
|
+
let lastEmittedClientX;
|
|
11
|
+
let lastEmittedClientY;
|
|
12
|
+
const emitMove = (e) => {
|
|
13
|
+
lastEmittedClientX = e.clientX;
|
|
14
|
+
lastEmittedClientY = e.clientY;
|
|
15
|
+
callBack({
|
|
16
|
+
pageX: e.pageX,
|
|
17
|
+
pageY: e.pageY,
|
|
18
|
+
clientX: e.clientX,
|
|
19
|
+
clientY: e.clientY,
|
|
20
|
+
}, () => {
|
|
21
|
+
onMouseupWindow();
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
const throttledCallBack = interval <= 0
|
|
25
|
+
? Object.assign((e) => emitMove(e), {
|
|
26
|
+
cancel: () => undefined,
|
|
27
|
+
flush: () => undefined,
|
|
28
|
+
})
|
|
29
|
+
: throttle(emitMove, interval);
|
|
30
|
+
const onMousemoveWindow = (e) => {
|
|
31
|
+
hasMoveEvent = true;
|
|
32
|
+
throttledCallBack(e);
|
|
33
|
+
};
|
|
34
|
+
const onPointermoveWindow = (e) => {
|
|
35
|
+
if (typeof pointerId === 'number' && e.pointerId !== pointerId)
|
|
36
|
+
return;
|
|
37
|
+
hasMoveEvent = true;
|
|
38
|
+
throttledCallBack(e);
|
|
39
|
+
};
|
|
40
|
+
const onMouseleaveWindow = (e) => {
|
|
41
|
+
if (typeof pointerId === 'number')
|
|
42
|
+
return;
|
|
43
|
+
onMouseupWindow(e);
|
|
44
|
+
};
|
|
45
|
+
const shouldUseEndEventAsMove = (e) => {
|
|
46
|
+
if (e.clientX === lastEmittedClientX && e.clientY === lastEmittedClientY)
|
|
47
|
+
return false;
|
|
48
|
+
if (hasMoveEvent)
|
|
49
|
+
return true;
|
|
50
|
+
if (typeof initialClientX !== 'number')
|
|
51
|
+
return false;
|
|
52
|
+
return e.clientX !== initialClientX;
|
|
53
|
+
};
|
|
54
|
+
const onMouseupWindow = (e) => {
|
|
55
|
+
if (ended)
|
|
56
|
+
return;
|
|
57
|
+
ended = true;
|
|
58
|
+
ownerWindow.removeEventListener('mousemove', onMousemoveWindow, true);
|
|
59
|
+
ownerWindow.removeEventListener('mouseup', onMouseupWindow, true);
|
|
60
|
+
ownerWindow.removeEventListener('mouseleave', onMouseleaveWindow, true);
|
|
61
|
+
ownerWindow.removeEventListener('pointermove', onPointermoveWindow, true);
|
|
62
|
+
ownerWindow.removeEventListener('pointerup', onPointerupWindow, true);
|
|
63
|
+
ownerWindow.removeEventListener('pointercancel', onPointerupWindow, true);
|
|
64
|
+
if (typeof pointerId === 'number') {
|
|
65
|
+
try {
|
|
66
|
+
target?.releasePointerCapture?.(pointerId);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// Pointer capture can already be lost in Electron popup windows.
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (ownerBody) {
|
|
73
|
+
ownerBody.style.userSelect = 'inherit';
|
|
74
|
+
ownerBody.style.webkitUserSelect = 'inherit';
|
|
75
|
+
}
|
|
76
|
+
if (e && shouldUseEndEventAsMove(e)) {
|
|
77
|
+
throttledCallBack.cancel();
|
|
78
|
+
emitMove(e);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
throttledCallBack.flush?.();
|
|
82
|
+
}
|
|
83
|
+
throttledCallBack.cancel();
|
|
84
|
+
onEnd?.();
|
|
85
|
+
};
|
|
86
|
+
const onPointerupWindow = (e) => {
|
|
87
|
+
if (typeof pointerId === 'number' && e.pointerId !== pointerId)
|
|
88
|
+
return;
|
|
89
|
+
onMouseupWindow(e);
|
|
90
|
+
};
|
|
91
|
+
if (ownerBody) {
|
|
92
|
+
ownerBody.style.userSelect = 'none';
|
|
93
|
+
ownerBody.style.webkitUserSelect = 'none';
|
|
94
|
+
}
|
|
95
|
+
if (canUsePointerCapture && typeof pointerId === 'number') {
|
|
96
|
+
try {
|
|
97
|
+
target?.setPointerCapture?.(pointerId);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// Continue with ownerWindow listeners when capture is unavailable or rejected.
|
|
101
|
+
}
|
|
102
|
+
ownerWindow.addEventListener('mousemove', onMousemoveWindow, true);
|
|
103
|
+
ownerWindow.addEventListener('mouseup', onMouseupWindow, true);
|
|
104
|
+
ownerWindow.addEventListener('mouseleave', onMouseleaveWindow, true);
|
|
105
|
+
ownerWindow.addEventListener('pointermove', onPointermoveWindow, true);
|
|
106
|
+
ownerWindow.addEventListener('pointerup', onPointerupWindow, true);
|
|
107
|
+
ownerWindow.addEventListener('pointercancel', onPointerupWindow, true);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
ownerWindow.addEventListener('mousemove', onMousemoveWindow, true);
|
|
111
|
+
ownerWindow.addEventListener('mouseup', onMouseupWindow, true);
|
|
112
|
+
ownerWindow.addEventListener('mouseleave', onMouseleaveWindow, true);
|
|
113
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { getCellValueByRowKey } from './getCellValue';
|
|
2
|
+
import { getColumnId } from './getColumnId';
|
|
3
|
+
import { filterRows } from './filterData';
|
|
4
|
+
function compareValues(aVal, bVal) {
|
|
5
|
+
const isANil = aVal === null || aVal === undefined;
|
|
6
|
+
const isBNil = bVal === null || bVal === undefined;
|
|
7
|
+
// null-last rule: null/undefined are always placed last regardless of direction
|
|
8
|
+
if (isANil && isBNil)
|
|
9
|
+
return 0;
|
|
10
|
+
if (isANil)
|
|
11
|
+
return 1;
|
|
12
|
+
if (isBNil)
|
|
13
|
+
return -1;
|
|
14
|
+
if (typeof aVal === 'number' && typeof bVal === 'number') {
|
|
15
|
+
return aVal - bVal;
|
|
16
|
+
}
|
|
17
|
+
if (aVal instanceof Date && bVal instanceof Date) {
|
|
18
|
+
return aVal.getTime() - bVal.getTime();
|
|
19
|
+
}
|
|
20
|
+
if (typeof aVal === 'boolean' && typeof bVal === 'boolean') {
|
|
21
|
+
return (aVal ? 1 : 0) - (bVal ? 1 : 0);
|
|
22
|
+
}
|
|
23
|
+
return String(aVal).localeCompare(String(bVal));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Pure data processing pipeline: filter then stable multi-sort.
|
|
27
|
+
*/
|
|
28
|
+
export function processDataQuery(params) {
|
|
29
|
+
const { data, columns, query, rowKey, includeRows = true } = params;
|
|
30
|
+
if (!data || data.length === 0) {
|
|
31
|
+
return {
|
|
32
|
+
rows: [],
|
|
33
|
+
data: [],
|
|
34
|
+
sourceIndexByVisibleIndex: [],
|
|
35
|
+
visibleIndexBySourceIndex: new Map(),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
// 1. Filter rows
|
|
39
|
+
const filtered = filterRows(data, columns, query.filterParams || []);
|
|
40
|
+
// 2. Prepare column lookup
|
|
41
|
+
const columnMap = new Map();
|
|
42
|
+
columns.forEach(col => {
|
|
43
|
+
columnMap.set(getColumnId(col), col);
|
|
44
|
+
});
|
|
45
|
+
// 3. Sort rows if sortParams are present
|
|
46
|
+
const activeSortParams = (query.sortParams || [])
|
|
47
|
+
.filter(s => {
|
|
48
|
+
const id = s.columnId ?? s.key;
|
|
49
|
+
return id && columnMap.has(id);
|
|
50
|
+
})
|
|
51
|
+
.sort((a, b) => (a.index ?? 0) - (b.index ?? 0));
|
|
52
|
+
let sortedRows = filtered;
|
|
53
|
+
if (activeSortParams.length > 0) {
|
|
54
|
+
const sortColumns = activeSortParams.map(sortParam => {
|
|
55
|
+
const columnId = sortParam.columnId ?? sortParam.key;
|
|
56
|
+
return columnMap.get(columnId);
|
|
57
|
+
});
|
|
58
|
+
const sortValues = sortColumns.map(column => filtered.map(entry => getCellValueByRowKey(column.key, entry.item.values)));
|
|
59
|
+
const sortedIndexes = filtered.map((_, index) => index);
|
|
60
|
+
sortedIndexes.sort((aIndex, bIndex) => {
|
|
61
|
+
for (let i = 0; i < activeSortParams.length; i++) {
|
|
62
|
+
const sortParam = activeSortParams[i];
|
|
63
|
+
const column = sortColumns[i];
|
|
64
|
+
const aRaw = sortValues[i][aIndex];
|
|
65
|
+
const bRaw = sortValues[i][bIndex];
|
|
66
|
+
const isANil = aRaw === null || aRaw === undefined;
|
|
67
|
+
const isBNil = bRaw === null || bRaw === undefined;
|
|
68
|
+
let comparison = 0;
|
|
69
|
+
if (isANil || isBNil) {
|
|
70
|
+
// null-last rule: null/undefined always placed at the end regardless of asc/desc
|
|
71
|
+
comparison = isANil && isBNil ? 0 : isANil ? 1 : -1;
|
|
72
|
+
}
|
|
73
|
+
else if (column.sortComparator) {
|
|
74
|
+
const customResult = column.sortComparator(aRaw, bRaw, {
|
|
75
|
+
column,
|
|
76
|
+
aItem: filtered[aIndex].item,
|
|
77
|
+
bItem: filtered[bIndex].item,
|
|
78
|
+
});
|
|
79
|
+
comparison = sortParam.orderBy === 'desc' ? -customResult : customResult;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const rawComp = compareValues(aRaw, bRaw);
|
|
83
|
+
comparison = sortParam.orderBy === 'desc' ? -rawComp : rawComp;
|
|
84
|
+
}
|
|
85
|
+
if (comparison !== 0) {
|
|
86
|
+
return comparison;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Stable tie-breaker: preserve original sourceIndex
|
|
90
|
+
return filtered[aIndex].sourceIndex - filtered[bIndex].sourceIndex;
|
|
91
|
+
});
|
|
92
|
+
sortedRows = sortedIndexes.map(index => filtered[index]);
|
|
93
|
+
}
|
|
94
|
+
// 4. Build output structures
|
|
95
|
+
const rows = [];
|
|
96
|
+
const processedData = [];
|
|
97
|
+
const sourceIndexByVisibleIndex = [];
|
|
98
|
+
const visibleIndexBySourceIndex = new Map();
|
|
99
|
+
for (let visibleIndex = 0; visibleIndex < sortedRows.length; visibleIndex++) {
|
|
100
|
+
const entry = sortedRows[visibleIndex];
|
|
101
|
+
if (includeRows) {
|
|
102
|
+
const itemRowKey = rowKey ? getCellValueByRowKey(rowKey, entry.item.values) : undefined;
|
|
103
|
+
rows.push({
|
|
104
|
+
item: entry.item,
|
|
105
|
+
sourceIndex: entry.sourceIndex,
|
|
106
|
+
rowKey: itemRowKey,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
processedData.push(entry.item);
|
|
110
|
+
sourceIndexByVisibleIndex.push(entry.sourceIndex);
|
|
111
|
+
visibleIndexBySourceIndex.set(entry.sourceIndex, visibleIndex);
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
rows,
|
|
115
|
+
data: processedData,
|
|
116
|
+
sourceIndexByVisibleIndex,
|
|
117
|
+
visibleIndexBySourceIndex,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { BGridDataItemStatus } from '../types';
|
|
2
|
+
export function moveRowItem(items, fromIndex, toIndex) {
|
|
3
|
+
if (fromIndex < 0 ||
|
|
4
|
+
toIndex < 0 ||
|
|
5
|
+
fromIndex >= items.length ||
|
|
6
|
+
toIndex >= items.length ||
|
|
7
|
+
fromIndex === toIndex) {
|
|
8
|
+
return [...items];
|
|
9
|
+
}
|
|
10
|
+
const nextItems = [...items];
|
|
11
|
+
const source = nextItems.splice(fromIndex, 1)[0];
|
|
12
|
+
nextItems.splice(toIndex, 0, { ...source, status: BGridDataItemStatus.edit });
|
|
13
|
+
return nextItems;
|
|
14
|
+
}
|
|
15
|
+
export function remapRowIndex(index, fromIndex, toIndex) {
|
|
16
|
+
if (index === fromIndex)
|
|
17
|
+
return toIndex;
|
|
18
|
+
if (fromIndex < toIndex && index > fromIndex && index <= toIndex)
|
|
19
|
+
return index - 1;
|
|
20
|
+
if (toIndex < fromIndex && index >= toIndex && index < fromIndex)
|
|
21
|
+
return index + 1;
|
|
22
|
+
return index;
|
|
23
|
+
}
|
|
24
|
+
export function remapCheckedIndexesMap(checkedIndexesMap, fromIndex, toIndex) {
|
|
25
|
+
const next = new Map();
|
|
26
|
+
checkedIndexesMap.forEach((value, index) => {
|
|
27
|
+
next.set(remapRowIndex(index, fromIndex, toIndex), value);
|
|
28
|
+
});
|
|
29
|
+
return next;
|
|
30
|
+
}
|
|
31
|
+
export function getRowReorderTargetIndex(params) {
|
|
32
|
+
const { fromIndex, pointerOffsetY, rowHeight, rowCount } = params;
|
|
33
|
+
if (rowCount <= 0 || rowHeight <= 0)
|
|
34
|
+
return -1;
|
|
35
|
+
return clamp(Math.round(fromIndex + pointerOffsetY / rowHeight), 0, rowCount - 1);
|
|
36
|
+
}
|
|
37
|
+
export function getRowReorderOffset(params) {
|
|
38
|
+
const { rowIndex, fromIndex, toIndex, rowHeight } = params;
|
|
39
|
+
if (rowIndex === fromIndex)
|
|
40
|
+
return 0;
|
|
41
|
+
if (fromIndex < toIndex && rowIndex > fromIndex && rowIndex <= toIndex)
|
|
42
|
+
return -rowHeight;
|
|
43
|
+
if (toIndex < fromIndex && rowIndex >= toIndex && rowIndex < fromIndex)
|
|
44
|
+
return rowHeight;
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
export function getRowReorderRole(params) {
|
|
48
|
+
const { rowIndex, fromIndex, toIndex } = params;
|
|
49
|
+
if (rowIndex === fromIndex)
|
|
50
|
+
return 'source';
|
|
51
|
+
if (rowIndex === toIndex && toIndex !== fromIndex)
|
|
52
|
+
return 'target';
|
|
53
|
+
if (fromIndex < toIndex && rowIndex > fromIndex && rowIndex < toIndex)
|
|
54
|
+
return 'shift';
|
|
55
|
+
if (toIndex < fromIndex && rowIndex > toIndex && rowIndex < fromIndex)
|
|
56
|
+
return 'shift';
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
export function getMaxTransitionTimeMs(style) {
|
|
60
|
+
const durations = parseTimeList(style.transitionDuration);
|
|
61
|
+
const delays = parseTimeList(style.transitionDelay);
|
|
62
|
+
const count = Math.max(durations.length, delays.length);
|
|
63
|
+
let maximum = 0;
|
|
64
|
+
for (let index = 0; index < count; index++) {
|
|
65
|
+
const duration = durations[index % Math.max(durations.length, 1)] ?? 0;
|
|
66
|
+
const delay = delays[index % Math.max(delays.length, 1)] ?? 0;
|
|
67
|
+
maximum = Math.max(maximum, duration + delay);
|
|
68
|
+
}
|
|
69
|
+
return maximum;
|
|
70
|
+
}
|
|
71
|
+
function parseTimeList(value) {
|
|
72
|
+
if (!value.trim())
|
|
73
|
+
return [0];
|
|
74
|
+
return value.split(',').map(part => {
|
|
75
|
+
const token = part.trim();
|
|
76
|
+
if (token.endsWith('ms'))
|
|
77
|
+
return Number.parseFloat(token) || 0;
|
|
78
|
+
if (token.endsWith('s'))
|
|
79
|
+
return (Number.parseFloat(token) || 0) * 1000;
|
|
80
|
+
return Number.parseFloat(token) || 0;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function clamp(value, minimum, maximum) {
|
|
84
|
+
return Math.min(Math.max(value, minimum), maximum);
|
|
85
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { toMoney } from './number';
|
|
2
|
+
export function resolveStatusOptions(options) {
|
|
3
|
+
return {
|
|
4
|
+
visible: options?.visible ?? true,
|
|
5
|
+
configured: options !== undefined,
|
|
6
|
+
content: options?.content,
|
|
7
|
+
className: options?.className,
|
|
8
|
+
style: options?.style,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export function resolvePaginationViewOptions(options) {
|
|
12
|
+
return {
|
|
13
|
+
visible: options?.visible ?? true,
|
|
14
|
+
className: options?.className,
|
|
15
|
+
style: options?.style,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function resolveScrollbarOptions(options) {
|
|
19
|
+
const variant = options?.variant ?? 'modern';
|
|
20
|
+
return {
|
|
21
|
+
variant,
|
|
22
|
+
horizontal: {
|
|
23
|
+
visible: options?.horizontal?.visible ?? true,
|
|
24
|
+
className: options?.horizontal?.className,
|
|
25
|
+
style: options?.horizontal?.style,
|
|
26
|
+
},
|
|
27
|
+
vertical: {
|
|
28
|
+
visible: options?.vertical?.visible ?? true,
|
|
29
|
+
className: options?.vertical?.className,
|
|
30
|
+
style: options?.vertical?.style,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export function shouldRenderBottomBar(params) {
|
|
35
|
+
const hasDockedHorizontalScrollbar = params.scrollbar.variant !== 'native' &&
|
|
36
|
+
params.scrollbar.horizontal.visible &&
|
|
37
|
+
(params.hasHorizontalOverflow ?? true);
|
|
38
|
+
const hasPageSection = params.hasPage &&
|
|
39
|
+
(params.status.visible || params.pagination.visible);
|
|
40
|
+
const hasStatus = params.status.visible;
|
|
41
|
+
return hasPageSection || hasDockedHorizontalScrollbar || hasStatus;
|
|
42
|
+
}
|
|
43
|
+
export function resolveStatusContent(content, context) {
|
|
44
|
+
if (typeof content === 'function') {
|
|
45
|
+
return content(context);
|
|
46
|
+
}
|
|
47
|
+
if (content !== undefined) {
|
|
48
|
+
return content;
|
|
49
|
+
}
|
|
50
|
+
return `${toMoney(context.totalItems)} Items`;
|
|
51
|
+
}
|