beautiful-grid 1.0.13 → 1.0.15
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/README.md +121 -6
- package/cjs/BGrid.js +388 -44
- package/cjs/components/CellNavigationDomSync.js +8 -0
- package/cjs/components/CellTextEditorGateway.js +13 -9
- package/cjs/components/ColResizer.js +13 -7
- package/cjs/components/MasterDetailCell.js +145 -0
- package/cjs/components/MasterDetailContext.js +42 -0
- package/cjs/components/Table.js +162 -52
- package/cjs/components/TableBody.js +7 -3
- package/cjs/components/TableBodyCell.js +2 -1
- package/cjs/components/TableSummary.js +25 -34
- package/cjs/components/TableSummaryFronzen.js +36 -34
- package/cjs/store/createAppStore.js +2 -0
- package/cjs/utils/cellSelectionGeometry.js +32 -6
- package/cjs/utils/columnVisibility.js +17 -14
- package/cjs/utils/index.js +1 -0
- package/cjs/utils/rowHeightMetrics.js +47 -6
- package/cjs/utils/summary.js +55 -0
- package/cjs/utils/useRowReorderController.js +5 -1
- package/esm/BGrid.js +387 -72
- package/esm/components/CellNavigationDomSync.js +8 -0
- package/esm/components/CellTextEditorGateway.js +12 -9
- package/esm/components/ColResizer.js +8 -2
- package/esm/components/MasterDetailCell.js +101 -0
- package/esm/components/MasterDetailContext.js +5 -0
- package/esm/components/Table.js +151 -42
- package/esm/components/TableBody.js +6 -2
- package/esm/components/TableBodyCell.js +2 -1
- package/esm/components/TableSummary.js +26 -29
- package/esm/components/TableSummaryFronzen.js +26 -29
- package/esm/store/createAppStore.js +2 -0
- package/esm/utils/cellSelectionGeometry.js +31 -5
- package/esm/utils/columnVisibility.js +21 -18
- package/esm/utils/index.js +1 -0
- package/esm/utils/rowHeightMetrics.js +46 -6
- package/esm/utils/summary.js +35 -0
- package/esm/utils/useRowReorderController.js +5 -1
- package/package.json +1 -1
- package/style.css +164 -14
- package/types/BGrid.d.ts +1 -1
- package/types/components/MasterDetailCell.d.ts +21 -0
- package/types/components/MasterDetailContext.d.ts +20 -0
- package/types/components/Table.d.ts +1 -0
- package/types/components/TableBody.d.ts +2 -1
- package/types/store/createAppStore.d.ts +1 -1
- package/types/types.d.ts +70 -4
- package/types/utils/cellSelectionGeometry.d.ts +3 -1
- package/types/utils/index.d.ts +1 -0
- package/types/utils/rowHeightMetrics.d.ts +15 -1
- package/types/utils/summary.d.ts +13 -0
|
@@ -2,57 +2,54 @@ import { useMemo } from 'react';
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { useShallow } from 'zustand/react/shallow';
|
|
4
4
|
import { useAppStore } from '../store';
|
|
5
|
+
import { buildSummaryRowCells, normalizeSummaryRows } from '../utils';
|
|
5
6
|
import TableColGroup from './TableColGroup';
|
|
6
7
|
export function TableSummary({ position }) {
|
|
7
8
|
// [Selector Group 1] Summary Configuration - 요약 설정
|
|
8
|
-
const { summaryHeight, summary, columns,
|
|
9
|
+
const { summaryHeight, summaryRowHeight, summary, columns, frozenColumnIndex, variant, data } = useAppStore(useShallow(s => ({
|
|
9
10
|
summaryHeight: s.summaryHeight,
|
|
11
|
+
summaryRowHeight: s.summaryRowHeight,
|
|
10
12
|
summary: s.summary,
|
|
11
13
|
columns: s.columns,
|
|
12
|
-
columnsGroup: s.columnsGroup,
|
|
13
14
|
frozenColumnIndex: s.frozenColumnIndex,
|
|
14
15
|
variant: s.variant,
|
|
15
16
|
data: s.data,
|
|
16
17
|
})));
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (ignoreColumnCnt > 0) {
|
|
27
|
-
ignoreColumnCnt--;
|
|
28
|
-
return {};
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return {
|
|
32
|
-
column,
|
|
33
|
-
columnIndex,
|
|
34
|
-
summaryColumn,
|
|
35
|
-
};
|
|
36
|
-
});
|
|
37
|
-
}, [columns, frozenColumnIndex, summary]);
|
|
18
|
+
const summaryRows = useMemo(() => normalizeSummaryRows(summary), [summary]);
|
|
19
|
+
const renderedRows = useMemo(() => {
|
|
20
|
+
const targetColumns = columns.slice(frozenColumnIndex);
|
|
21
|
+
return summaryRows.map((row, rowIndex) => ({
|
|
22
|
+
row,
|
|
23
|
+
rowIndex,
|
|
24
|
+
cells: buildSummaryRowCells(targetColumns, row.columns, frozenColumnIndex),
|
|
25
|
+
}));
|
|
26
|
+
}, [summaryRows, columns, frozenColumnIndex]);
|
|
38
27
|
return (React.createElement(SummaryTable, { variant: variant, summaryHeight: summaryHeight, position: position },
|
|
39
28
|
React.createElement(TableColGroup, null),
|
|
40
|
-
React.createElement("tbody", { role: 'rfdg-summary' },
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
29
|
+
React.createElement("tbody", { role: 'rfdg-summary' }, renderedRows.map(({ row, rowIndex, cells }) => {
|
|
30
|
+
const rowHeight = row.height ?? summaryRowHeight;
|
|
31
|
+
return (React.createElement("tr", { key: row.id ?? rowIndex, className: ['bgrid-summary-row', row.className ?? ''].filter(Boolean).join(' '), style: {
|
|
32
|
+
...(rowHeight !== undefined ? { height: rowHeight } : {}),
|
|
33
|
+
...row.style,
|
|
34
|
+
} },
|
|
35
|
+
cells.map((cell, index) => {
|
|
36
|
+
if (!cell || !cell.column)
|
|
44
37
|
return null;
|
|
38
|
+
const { column, summaryColumn, columnIndex } = cell;
|
|
45
39
|
if (!summaryColumn)
|
|
46
40
|
return React.createElement("td", { key: index });
|
|
47
|
-
return (React.createElement("td", { key: index, style: {
|
|
41
|
+
return (React.createElement("td", { key: index, className: summaryColumn.className, style: {
|
|
48
42
|
textAlign: summaryColumn.align,
|
|
43
|
+
...summaryColumn.style,
|
|
49
44
|
}, colSpan: summaryColumn.colSpan ?? 1 }, summaryColumn.itemRender?.({
|
|
50
45
|
column,
|
|
51
46
|
columnIndex,
|
|
47
|
+
rowIndex,
|
|
52
48
|
data,
|
|
53
49
|
})));
|
|
54
50
|
}),
|
|
55
|
-
React.createElement("td", { "data-none": true })))
|
|
51
|
+
React.createElement("td", { "data-none": true })));
|
|
52
|
+
}))));
|
|
56
53
|
}
|
|
57
54
|
export function SummaryTable({ summaryHeight, variant, position, className, children, ...rest }) {
|
|
58
55
|
return (React.createElement("table", { className: [
|
|
@@ -2,16 +2,17 @@ import * as React from 'react';
|
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
3
|
import { useShallow } from 'zustand/react/shallow';
|
|
4
4
|
import { useAppStore } from '../store';
|
|
5
|
+
import { buildSummaryRowCells, normalizeSummaryRows } from '../utils';
|
|
5
6
|
import TableColGroupFrozen from './TableColGroupFrozen';
|
|
6
7
|
import { HeadTd } from './TableHead';
|
|
7
8
|
import { SummaryTable } from './TableSummary';
|
|
8
9
|
export function TableSummaryFrozen({ position }) {
|
|
9
10
|
// [Selector Group 1] Summary Configuration - 요약 설정
|
|
10
|
-
const { summaryHeight, summary, columns,
|
|
11
|
+
const { summaryHeight, summaryRowHeight, summary, columns, frozenColumnIndex, variant, data, showLineNumber, rowChecked, } = useAppStore(useShallow(s => ({
|
|
11
12
|
summaryHeight: s.summaryHeight,
|
|
13
|
+
summaryRowHeight: s.summaryRowHeight,
|
|
12
14
|
summary: s.summary,
|
|
13
15
|
columns: s.columns,
|
|
14
|
-
columnsGroup: s.columnsGroup,
|
|
15
16
|
frozenColumnIndex: s.frozenColumnIndex,
|
|
16
17
|
variant: s.variant,
|
|
17
18
|
data: s.data,
|
|
@@ -19,44 +20,40 @@ export function TableSummaryFrozen({ position }) {
|
|
|
19
20
|
rowChecked: s.rowChecked,
|
|
20
21
|
})));
|
|
21
22
|
const hasRowSelection = !!rowChecked;
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (ignoreColumnCnt > 0) {
|
|
32
|
-
ignoreColumnCnt--;
|
|
33
|
-
return {};
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return {
|
|
37
|
-
column,
|
|
38
|
-
columnIndex,
|
|
39
|
-
summaryColumn,
|
|
40
|
-
};
|
|
41
|
-
});
|
|
42
|
-
}, [columns, frozenColumnIndex, summary]);
|
|
23
|
+
const summaryRows = useMemo(() => normalizeSummaryRows(summary), [summary]);
|
|
24
|
+
const renderedRows = useMemo(() => {
|
|
25
|
+
const targetColumns = columns.slice(0, frozenColumnIndex);
|
|
26
|
+
return summaryRows.map((row, rowIndex) => ({
|
|
27
|
+
row,
|
|
28
|
+
rowIndex,
|
|
29
|
+
cells: buildSummaryRowCells(targetColumns, row.columns, 0),
|
|
30
|
+
}));
|
|
31
|
+
}, [summaryRows, columns, frozenColumnIndex]);
|
|
43
32
|
return (React.createElement(SummaryTable, { variant: variant, summaryHeight: summaryHeight, position: position },
|
|
44
33
|
React.createElement(TableColGroupFrozen, null),
|
|
45
|
-
React.createElement("tbody", { role: 'rfdg-summay-frozen' },
|
|
46
|
-
|
|
34
|
+
React.createElement("tbody", { role: 'rfdg-summay-frozen' }, renderedRows.map(({ row, rowIndex, cells }) => {
|
|
35
|
+
const rowHeight = row.height ?? summaryRowHeight;
|
|
36
|
+
return (React.createElement("tr", { key: row.id ?? rowIndex, className: ['bgrid-summary-row', row.className ?? ''].filter(Boolean).join(' '), style: {
|
|
37
|
+
...(rowHeight !== undefined ? { height: rowHeight } : {}),
|
|
38
|
+
...row.style,
|
|
39
|
+
} },
|
|
47
40
|
showLineNumber && React.createElement(HeadTd, { className: !hasRowSelection ? 'bordered' : '' }, "\u00A0"),
|
|
48
41
|
hasRowSelection && React.createElement("td", { className: 'bordered' }, "\u00A0"),
|
|
49
|
-
|
|
50
|
-
if (!column)
|
|
42
|
+
cells.map((cell, index) => {
|
|
43
|
+
if (!cell || !cell.column)
|
|
51
44
|
return null;
|
|
45
|
+
const { column, summaryColumn, columnIndex } = cell;
|
|
52
46
|
if (!summaryColumn)
|
|
53
47
|
return React.createElement("td", { key: index });
|
|
54
|
-
return (React.createElement("td", { key: index, style: {
|
|
48
|
+
return (React.createElement("td", { key: index, className: summaryColumn.className, style: {
|
|
55
49
|
textAlign: summaryColumn.align,
|
|
50
|
+
...summaryColumn.style,
|
|
56
51
|
}, colSpan: summaryColumn.colSpan ?? 1 }, summaryColumn.itemRender?.({
|
|
57
52
|
column,
|
|
58
53
|
columnIndex,
|
|
54
|
+
rowIndex,
|
|
59
55
|
data,
|
|
60
56
|
})));
|
|
61
|
-
})))
|
|
57
|
+
})));
|
|
58
|
+
}))));
|
|
62
59
|
}
|
|
@@ -77,6 +77,7 @@ export function AppStoreProvider({ children, initialState }) {
|
|
|
77
77
|
visible: true,
|
|
78
78
|
},
|
|
79
79
|
summaryHeight: initialState?.summaryHeight ?? 30,
|
|
80
|
+
summaryRowHeight: initialState?.summaryRowHeight,
|
|
80
81
|
itemHeight: initialState?.itemHeight ?? 15,
|
|
81
82
|
itemPadding: initialState?.itemPadding ?? 7,
|
|
82
83
|
frozenColumnIndex: initialState?.frozenColumnIndex ?? 0,
|
|
@@ -779,6 +780,7 @@ export function AppStoreProvider({ children, initialState }) {
|
|
|
779
780
|
setHeaderHeight: headerHeight => set({ headerHeight }),
|
|
780
781
|
setFooterHeight: footerHeight => set({ footerHeight }),
|
|
781
782
|
setSummaryHeight: summaryHeight => set({ summaryHeight }),
|
|
783
|
+
setSummaryRowHeight: summaryRowHeight => set({ summaryRowHeight }),
|
|
782
784
|
setItemHeight: itemHeight => set({ itemHeight }),
|
|
783
785
|
setItemPadding: itemPadding => set({ itemPadding }),
|
|
784
786
|
setFrozenColumnIndex: frozenColumnIndex => set({ frozenColumnIndex }),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function getCellSelectionFragments({ ranges, columns, rowCount, rowHeight, frozenColumnCount, frozenRowCount, frozenColumnsWidth, rowOffsets, }) {
|
|
1
|
+
export function getCellSelectionFragments({ ranges, columns, rowCount, rowHeight, frozenColumnCount, frozenRowCount, frozenColumnsWidth, rowOffsets, rowHeights, detailHeights, }) {
|
|
2
2
|
const safeRowCount = Math.max(0, Math.floor(rowCount));
|
|
3
3
|
const safeColumnCount = columns.length;
|
|
4
4
|
const safeRowHeight = Math.max(1, rowHeight);
|
|
@@ -38,6 +38,8 @@ export function getCellSelectionFragments({ ranges, columns, rowCount, rowHeight
|
|
|
38
38
|
selectedColumns,
|
|
39
39
|
rowHeight: safeRowHeight,
|
|
40
40
|
rowOffsets,
|
|
41
|
+
rowHeights,
|
|
42
|
+
detailHeights,
|
|
41
43
|
left: frozenDataOffset + getColumnsWidth(columns, 0, leftColumns.start - 1),
|
|
42
44
|
width: getColumnsWidth(columns, leftColumns.start, leftColumns.end),
|
|
43
45
|
top: getRowsTop(topRows.start, 0, safeRowHeight, rowOffsets),
|
|
@@ -53,6 +55,8 @@ export function getCellSelectionFragments({ ranges, columns, rowCount, rowHeight
|
|
|
53
55
|
selectedColumns,
|
|
54
56
|
rowHeight: safeRowHeight,
|
|
55
57
|
rowOffsets,
|
|
58
|
+
rowHeights,
|
|
59
|
+
detailHeights,
|
|
56
60
|
left: getMainColumnLeft(columns, mainColumns.start, safeFrozenColumnCount),
|
|
57
61
|
width: getMainColumnRight(columns, mainColumns.end, safeFrozenColumnCount) -
|
|
58
62
|
getMainColumnLeft(columns, mainColumns.start, safeFrozenColumnCount),
|
|
@@ -69,6 +73,8 @@ export function getCellSelectionFragments({ ranges, columns, rowCount, rowHeight
|
|
|
69
73
|
selectedColumns,
|
|
70
74
|
rowHeight: safeRowHeight,
|
|
71
75
|
rowOffsets,
|
|
76
|
+
rowHeights,
|
|
77
|
+
detailHeights,
|
|
72
78
|
left: frozenDataOffset + getColumnsWidth(columns, 0, leftColumns.start - 1),
|
|
73
79
|
width: getColumnsWidth(columns, leftColumns.start, leftColumns.end),
|
|
74
80
|
top: getRowsTop(bodyRows.start, safeFrozenRowCount, safeRowHeight, rowOffsets),
|
|
@@ -84,6 +90,8 @@ export function getCellSelectionFragments({ ranges, columns, rowCount, rowHeight
|
|
|
84
90
|
selectedColumns,
|
|
85
91
|
rowHeight: safeRowHeight,
|
|
86
92
|
rowOffsets,
|
|
93
|
+
rowHeights,
|
|
94
|
+
detailHeights,
|
|
87
95
|
left: getMainColumnLeft(columns, mainColumns.start, safeFrozenColumnCount),
|
|
88
96
|
width: getMainColumnRight(columns, mainColumns.end, safeFrozenColumnCount) -
|
|
89
97
|
getMainColumnLeft(columns, mainColumns.start, safeFrozenColumnCount),
|
|
@@ -126,16 +134,14 @@ export function normalizeCellSelectionRange(range) {
|
|
|
126
134
|
endColumnIndex: Math.max(range.startColumnIndex, range.endColumnIndex),
|
|
127
135
|
};
|
|
128
136
|
}
|
|
129
|
-
function createFragment({ rangeIndex, quadrant, rows, columns, selectedRows, selectedColumns, rowHeight, rowOffsets, left, top, width, }) {
|
|
137
|
+
function createFragment({ rangeIndex, quadrant, rows, columns, selectedRows, selectedColumns, rowHeight, rowOffsets, rowHeights, detailHeights, left, top, width, }) {
|
|
130
138
|
return {
|
|
131
139
|
rangeIndex,
|
|
132
140
|
quadrant,
|
|
133
141
|
left,
|
|
134
142
|
top,
|
|
135
143
|
width,
|
|
136
|
-
height: rowOffsets
|
|
137
|
-
? (rowOffsets[rows.end + 1] ?? 0) - (rowOffsets[rows.start] ?? 0)
|
|
138
|
-
: (rows.end - rows.start + 1) * rowHeight,
|
|
144
|
+
height: getRowsHeight(rows.start, rows.end, rowHeight, rowOffsets, rowHeights, detailHeights),
|
|
139
145
|
edges: {
|
|
140
146
|
top: rows.start === selectedRows.start,
|
|
141
147
|
right: columns.end === selectedColumns.end,
|
|
@@ -144,6 +150,26 @@ function createFragment({ rangeIndex, quadrant, rows, columns, selectedRows, sel
|
|
|
144
150
|
},
|
|
145
151
|
};
|
|
146
152
|
}
|
|
153
|
+
function getRowsHeight(start, end, rowHeight, rowOffsets, rowHeights, detailHeights) {
|
|
154
|
+
if (rowHeights && rowHeights[end] !== undefined) {
|
|
155
|
+
const endRowHeight = rowHeights[end];
|
|
156
|
+
if (start === end)
|
|
157
|
+
return endRowHeight;
|
|
158
|
+
const topStart = rowOffsets ? rowOffsets[start] ?? 0 : start * rowHeight;
|
|
159
|
+
const topEnd = rowOffsets ? rowOffsets[end] ?? 0 : end * rowHeight;
|
|
160
|
+
return topEnd + endRowHeight - topStart;
|
|
161
|
+
}
|
|
162
|
+
if (rowOffsets) {
|
|
163
|
+
const topStart = rowOffsets[start] ?? 0;
|
|
164
|
+
const topEnd = rowOffsets[end] ?? 0;
|
|
165
|
+
const detailEnd = detailHeights?.[end] ?? 0;
|
|
166
|
+
const endRowHeight = Math.max((rowOffsets[end + 1] ?? (topEnd + rowHeight)) - topEnd - detailEnd, 0);
|
|
167
|
+
if (start === end)
|
|
168
|
+
return endRowHeight;
|
|
169
|
+
return topEnd + endRowHeight - topStart;
|
|
170
|
+
}
|
|
171
|
+
return (end - start + 1) * rowHeight;
|
|
172
|
+
}
|
|
147
173
|
function getRowsTop(start, base, rowHeight, rowOffsets) {
|
|
148
174
|
return rowOffsets ? (rowOffsets[start] ?? 0) - (rowOffsets[base] ?? 0) : (start - base) * rowHeight;
|
|
149
175
|
}
|
|
@@ -66,24 +66,27 @@ function projectCellMergeOptions(options, visibleIndexByOriginalIndex) {
|
|
|
66
66
|
}, {});
|
|
67
67
|
return { ...options, columnsMap };
|
|
68
68
|
}
|
|
69
|
-
function
|
|
69
|
+
function projectSummaryColumn(sc, vMap) {
|
|
70
|
+
const end = sc.columnIndex + (sc.colSpan ?? 1);
|
|
71
|
+
const idxs = [];
|
|
72
|
+
for (let i = sc.columnIndex; i < end; i++) {
|
|
73
|
+
const v = vMap.get(i);
|
|
74
|
+
if (v !== undefined)
|
|
75
|
+
idxs.push(v);
|
|
76
|
+
}
|
|
77
|
+
return idxs.length ? [{ ...sc, columnIndex: idxs[0], colSpan: idxs.length }] : [];
|
|
78
|
+
}
|
|
79
|
+
function projectSummary(summary, vMap) {
|
|
70
80
|
if (!summary)
|
|
71
81
|
return undefined;
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return [{
|
|
83
|
-
...summaryColumn,
|
|
84
|
-
columnIndex: visibleIndexes[0],
|
|
85
|
-
colSpan: visibleIndexes.length,
|
|
86
|
-
}];
|
|
87
|
-
});
|
|
88
|
-
return { ...summary, columns };
|
|
82
|
+
const projectCols = (cols) => cols.flatMap(c => projectSummaryColumn(c, vMap));
|
|
83
|
+
return {
|
|
84
|
+
...summary,
|
|
85
|
+
...(summary.columns ? { columns: projectCols(summary.columns) } : {}),
|
|
86
|
+
...(summary.rows
|
|
87
|
+
? {
|
|
88
|
+
rows: summary.rows.map(r => (Array.isArray(r) ? projectCols(r) : { ...r, columns: projectCols(r.columns) })),
|
|
89
|
+
}
|
|
90
|
+
: {}),
|
|
91
|
+
};
|
|
89
92
|
}
|
package/esm/utils/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export function createRowHeightMetrics(data, fallbackHeight, getRowHeight) {
|
|
1
|
+
export function createRowHeightMetrics(data, fallbackHeight, getRowHeight, masterDetail) {
|
|
2
2
|
const safeFallback = Number.isFinite(fallbackHeight) && fallbackHeight > 0 ? fallbackHeight : 1;
|
|
3
|
-
|
|
3
|
+
const hasMasterDetail = Boolean(masterDetail && masterDetail.expandedKeysSet.size > 0);
|
|
4
|
+
if (!getRowHeight && !hasMasterDetail) {
|
|
4
5
|
return {
|
|
5
6
|
heights: new Float64Array(0),
|
|
6
7
|
offsets: new Float64Array(0),
|
|
@@ -10,17 +11,56 @@ export function createRowHeightMetrics(data, fallbackHeight, getRowHeight) {
|
|
|
10
11
|
}
|
|
11
12
|
const heights = new Float64Array(data.length);
|
|
12
13
|
const offsets = new Float64Array(data.length + 1);
|
|
14
|
+
const detailHeights = hasMasterDetail ? new Float64Array(data.length) : undefined;
|
|
13
15
|
for (let index = 0; index < data.length; index += 1) {
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const item = data[index];
|
|
17
|
+
const sourceIndex = masterDetail?.sourceIndexByVisibleIndex?.[index] ?? index;
|
|
18
|
+
let masterHeight = safeFallback;
|
|
19
|
+
if (getRowHeight) {
|
|
20
|
+
try {
|
|
21
|
+
const requestedHeight = getRowHeight(item.values, index);
|
|
22
|
+
masterHeight = Number.isFinite(requestedHeight) && requestedHeight > 0 ? requestedHeight : safeFallback;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
masterHeight = safeFallback;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
heights[index] = masterHeight;
|
|
29
|
+
let detailHeight = 0;
|
|
30
|
+
if (hasMasterDetail && masterDetail) {
|
|
31
|
+
const rowKey = masterDetail.getRowKey(item.values, index);
|
|
32
|
+
if (rowKey !== undefined && rowKey !== null && masterDetail.expandedKeysSet.has(rowKey)) {
|
|
33
|
+
let isExpandable = true;
|
|
34
|
+
if (masterDetail.hasDetail) {
|
|
35
|
+
try {
|
|
36
|
+
isExpandable = masterDetail.hasDetail(item, sourceIndex);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
isExpandable = false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (isExpandable) {
|
|
43
|
+
try {
|
|
44
|
+
const requestedDetailHeight = masterDetail.getDetailHeight(item, sourceIndex);
|
|
45
|
+
detailHeight =
|
|
46
|
+
Number.isFinite(requestedDetailHeight) && requestedDetailHeight > 0 ? requestedDetailHeight : 200;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
detailHeight = 200;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
detailHeights[index] = detailHeight;
|
|
54
|
+
}
|
|
55
|
+
const layoutHeight = masterHeight + detailHeight;
|
|
56
|
+
offsets[index + 1] = offsets[index] + layoutHeight;
|
|
18
57
|
}
|
|
19
58
|
return {
|
|
20
59
|
heights,
|
|
21
60
|
offsets,
|
|
22
61
|
totalHeight: offsets[data.length],
|
|
23
62
|
variable: true,
|
|
63
|
+
detailHeights,
|
|
24
64
|
};
|
|
25
65
|
}
|
|
26
66
|
/** Returns the row containing offset, or rowCount when offset is at/after the end. */
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export const DEFAULT_SUMMARY_ROW_HEIGHT = 30;
|
|
2
|
+
export function normalizeSummaryRows(summary) {
|
|
3
|
+
if (!summary)
|
|
4
|
+
return [];
|
|
5
|
+
if (summary.rows?.length) {
|
|
6
|
+
return summary.rows.map((row, idx) => Array.isArray(row) ? { id: idx, columns: row } : { ...row, id: row.id ?? idx });
|
|
7
|
+
}
|
|
8
|
+
return summary.columns?.length ? [{ id: 0, columns: summary.columns }] : [];
|
|
9
|
+
}
|
|
10
|
+
export function computeSummaryHeight(options) {
|
|
11
|
+
const { summary, summaryHeight, summaryRowHeight = DEFAULT_SUMMARY_ROW_HEIGHT } = options;
|
|
12
|
+
if (!summary)
|
|
13
|
+
return 0;
|
|
14
|
+
const rows = normalizeSummaryRows(summary);
|
|
15
|
+
if (!rows.length)
|
|
16
|
+
return 0;
|
|
17
|
+
return summaryHeight !== undefined
|
|
18
|
+
? summaryHeight
|
|
19
|
+
: rows.reduce((acc, row) => acc + (row.height ?? summaryRowHeight), 0);
|
|
20
|
+
}
|
|
21
|
+
export function buildSummaryRowCells(columns, summaryColumns, startIndex = 0) {
|
|
22
|
+
let ignoreCnt = 0;
|
|
23
|
+
return columns.map((column, i) => {
|
|
24
|
+
const columnIndex = startIndex + i;
|
|
25
|
+
const summaryColumn = summaryColumns?.find(sc => sc.columnIndex === columnIndex);
|
|
26
|
+
if (summaryColumn && (summaryColumn.colSpan ?? 1) > 1) {
|
|
27
|
+
ignoreCnt = (summaryColumn.colSpan ?? 1) - 1;
|
|
28
|
+
}
|
|
29
|
+
else if (ignoreCnt > 0) {
|
|
30
|
+
ignoreCnt--;
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return { column, columnIndex, summaryColumn };
|
|
34
|
+
});
|
|
35
|
+
}
|
|
@@ -333,7 +333,11 @@ export function useRowReorderController({ containerRef, bodyContainerRef, scroll
|
|
|
333
333
|
container.style.setProperty('--bgrid-row-reorder-height', `${session.rowHeight}px`);
|
|
334
334
|
store.getState().clearCellSelection();
|
|
335
335
|
store.getState().closeTransientSurfaces();
|
|
336
|
-
container.querySelectorAll('.bgrid-row-hover').forEach(element =>
|
|
336
|
+
container.querySelectorAll('.bgrid-row-hover').forEach(element => {
|
|
337
|
+
if (element.closest('[role="grid"], [role="treegrid"]') !== container)
|
|
338
|
+
return;
|
|
339
|
+
element.classList.remove('bgrid-row-hover');
|
|
340
|
+
});
|
|
337
341
|
store.setState({
|
|
338
342
|
reorderingInfo: {
|
|
339
343
|
fromIndex: session.fromIndex,
|