@glideappsfinal/glide-data-grid 6.0.9 → 6.0.11
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/build.sh +3 -1
- package/dist/cjs/data-editor/data-editor.js +40 -7
- package/dist/cjs/data-editor/data-editor.js.map +1 -1
- package/dist/cjs/internal/data-editor-container/data-grid-container.css +1 -0
- package/dist/cjs/internal/data-editor-container/data-grid-container.js +25 -30
- package/dist/cjs/internal/data-grid/data-grid.js +7 -8
- package/dist/cjs/internal/data-grid/data-grid.js.map +1 -1
- package/dist/cjs/internal/data-grid/render/data-grid-lib.js +25 -7
- package/dist/cjs/internal/data-grid/render/data-grid-lib.js.map +1 -1
- package/dist/cjs/internal/data-grid/render/data-grid-render.header.js +32 -7
- package/dist/cjs/internal/data-grid/render/data-grid-render.header.js.map +1 -1
- package/dist/cjs/internal/data-grid/render/data-grid-render.js +14 -6
- package/dist/cjs/internal/data-grid/render/data-grid-render.js.map +1 -1
- package/dist/cjs/internal/data-grid-overlay-editor/data-grid-overlay-editor-style.css +1 -0
- package/dist/cjs/internal/data-grid-overlay-editor/data-grid-overlay-editor-style.js +19 -75
- package/dist/cjs/internal/data-grid-overlay-editor/private/bubbles-overlay-editor-style.css +1 -0
- package/dist/cjs/internal/data-grid-overlay-editor/private/bubbles-overlay-editor-style.js +5 -32
- package/dist/cjs/internal/data-grid-overlay-editor/private/drilldown-overlay-editor.css +1 -0
- package/dist/cjs/internal/data-grid-overlay-editor/private/drilldown-overlay-editor.js +15 -45
- package/dist/cjs/internal/data-grid-overlay-editor/private/image-overlay-editor-style.css +1 -0
- package/dist/cjs/internal/data-grid-overlay-editor/private/image-overlay-editor-style.js +5 -54
- package/dist/cjs/internal/data-grid-overlay-editor/private/markdown-overlay-editor-style.css +1 -0
- package/dist/cjs/internal/data-grid-overlay-editor/private/markdown-overlay-editor-style.js +9 -74
- package/dist/cjs/internal/data-grid-overlay-editor/private/number-overlay-editor-style.css +1 -0
- package/dist/cjs/internal/data-grid-overlay-editor/private/number-overlay-editor-style.js +5 -13
- package/dist/cjs/internal/data-grid-overlay-editor/private/uri-overlay-editor-style.css +1 -0
- package/dist/cjs/internal/data-grid-overlay-editor/private/uri-overlay-editor-style.js +5 -51
- package/dist/cjs/internal/data-grid-search/data-grid-search-style.css +1 -0
- package/dist/cjs/internal/data-grid-search/data-grid-search-style.js +5 -94
- package/dist/cjs/internal/growing-entry/growing-entry-style.css +3 -0
- package/dist/cjs/internal/growing-entry/growing-entry-style.js +15 -58
- package/dist/cjs/internal/markdown-div/private/markdown-container.css +1 -0
- package/dist/cjs/internal/markdown-div/private/markdown-container.js +5 -17
- package/dist/cjs/internal/scrolling-data-grid/infinite-scroller.css +1 -0
- package/dist/cjs/internal/scrolling-data-grid/infinite-scroller.js +233 -231
- package/dist/dts/cells/boolean-cell.d.ts +0 -1
- package/dist/dts/cells/bubble-cell.d.ts +0 -1
- package/dist/dts/cells/cell-types.d.ts +0 -1
- package/dist/dts/cells/drilldown-cell.d.ts +0 -1
- package/dist/dts/cells/image-cell.d.ts +0 -1
- package/dist/dts/cells/index.d.ts +0 -1
- package/dist/dts/cells/loading-cell.d.ts +0 -1
- package/dist/dts/cells/markdown-cell.d.ts +0 -1
- package/dist/dts/cells/marker-cell.d.ts +0 -1
- package/dist/dts/cells/new-row-cell.d.ts +0 -1
- package/dist/dts/cells/number-cell.d.ts +0 -1
- package/dist/dts/cells/protected-cell.d.ts +0 -1
- package/dist/dts/cells/row-id-cell.d.ts +0 -1
- package/dist/dts/cells/text-cell.d.ts +0 -1
- package/dist/dts/cells/uri-cell.d.ts +0 -1
- package/dist/dts/common/browser-detect.d.ts +0 -1
- package/dist/dts/common/image-window-loader.d.ts +0 -1
- package/dist/dts/common/is-hotkey.d.ts +0 -1
- package/dist/dts/common/math.d.ts +0 -1
- package/dist/dts/common/render-state-provider.d.ts +0 -1
- package/dist/dts/common/resize-detector.d.ts +0 -1
- package/dist/dts/common/styles.d.ts +0 -1
- package/dist/dts/common/support.d.ts +0 -1
- package/dist/dts/common/utils.d.ts +0 -1
- package/dist/dts/data-editor/copy-paste.d.ts +0 -1
- package/dist/dts/data-editor/data-editor-fns.d.ts +0 -1
- package/dist/dts/data-editor/data-editor-keybindings.d.ts +0 -1
- package/dist/dts/data-editor/data-editor.d.ts +0 -1
- package/dist/dts/data-editor/data-editor.d.ts.map +1 -1
- package/dist/dts/data-editor/group-rename.d.ts +0 -1
- package/dist/dts/data-editor/row-grouping-api.d.ts +0 -1
- package/dist/dts/data-editor/row-grouping.d.ts +0 -1
- package/dist/dts/data-editor/use-autoscroll.d.ts +0 -1
- package/dist/dts/data-editor/use-cells-for-selection.d.ts +0 -1
- package/dist/dts/data-editor/use-column-sizer.d.ts +0 -1
- package/dist/dts/data-editor/use-initial-scroll-offset.d.ts +0 -1
- package/dist/dts/data-editor/use-rem-adjuster.d.ts +0 -1
- package/dist/dts/data-editor/visible-region.d.ts +0 -1
- package/dist/dts/data-editor-all.d.ts +0 -1
- package/dist/dts/index.d.ts +0 -1
- package/dist/dts/internal/click-outside-container/click-outside-container.d.ts +0 -1
- package/dist/dts/internal/data-editor-container/data-grid-container.d.ts +0 -1
- package/dist/dts/internal/data-grid/animation-manager.d.ts +0 -1
- package/dist/dts/internal/data-grid/cell-set.d.ts +0 -1
- package/dist/dts/internal/data-grid/color-parser.d.ts +0 -1
- package/dist/dts/internal/data-grid/data-grid-sprites.d.ts +0 -1
- package/dist/dts/internal/data-grid/data-grid-types.d.ts +0 -1
- package/dist/dts/internal/data-grid/data-grid.d.ts +0 -1
- package/dist/dts/internal/data-grid/data-grid.d.ts.map +1 -1
- package/dist/dts/internal/data-grid/event-args.d.ts +1 -2
- package/dist/dts/internal/data-grid/event-args.d.ts.map +1 -1
- package/dist/dts/internal/data-grid/image-window-loader-interface.d.ts +0 -1
- package/dist/dts/internal/data-grid/render/data-grid-lib.d.ts +1 -2
- package/dist/dts/internal/data-grid/render/data-grid-lib.d.ts.map +1 -1
- package/dist/dts/internal/data-grid/render/data-grid-render.blit.d.ts +0 -1
- package/dist/dts/internal/data-grid/render/data-grid-render.cells.d.ts +0 -1
- package/dist/dts/internal/data-grid/render/data-grid-render.d.ts +0 -1
- package/dist/dts/internal/data-grid/render/data-grid-render.d.ts.map +1 -1
- package/dist/dts/internal/data-grid/render/data-grid-render.header.d.ts +0 -1
- package/dist/dts/internal/data-grid/render/data-grid-render.header.d.ts.map +1 -1
- package/dist/dts/internal/data-grid/render/data-grid-render.lines.d.ts +0 -1
- package/dist/dts/internal/data-grid/render/data-grid-render.walk.d.ts +0 -1
- package/dist/dts/internal/data-grid/render/data-grid.render.rings.d.ts +0 -1
- package/dist/dts/internal/data-grid/render/draw-checkbox.d.ts +0 -1
- package/dist/dts/internal/data-grid/render/draw-edit-hover-indicator.d.ts +0 -1
- package/dist/dts/internal/data-grid/render/draw-grid-arg.d.ts +0 -1
- package/dist/dts/internal/data-grid/sprites.d.ts +0 -1
- package/dist/dts/internal/data-grid/use-animation-queue.d.ts +0 -1
- package/dist/dts/internal/data-grid/use-selection-behavior.d.ts +0 -1
- package/dist/dts/internal/data-grid-dnd/data-grid-dnd.d.ts +0 -1
- package/dist/dts/internal/data-grid-overlay-editor/data-grid-overlay-editor-style.d.ts +0 -1
- package/dist/dts/internal/data-grid-overlay-editor/data-grid-overlay-editor.d.ts +0 -1
- package/dist/dts/internal/data-grid-overlay-editor/private/bubbles-overlay-editor-style.d.ts +0 -1
- package/dist/dts/internal/data-grid-overlay-editor/private/bubbles-overlay-editor.d.ts +0 -1
- package/dist/dts/internal/data-grid-overlay-editor/private/drilldown-overlay-editor.d.ts +0 -1
- package/dist/dts/internal/data-grid-overlay-editor/private/image-overlay-editor-style.d.ts +0 -1
- package/dist/dts/internal/data-grid-overlay-editor/private/image-overlay-editor.d.ts +0 -1
- package/dist/dts/internal/data-grid-overlay-editor/private/markdown-overlay-editor-style.d.ts +0 -1
- package/dist/dts/internal/data-grid-overlay-editor/private/markdown-overlay-editor.d.ts +0 -1
- package/dist/dts/internal/data-grid-overlay-editor/private/number-overlay-editor-style.d.ts +0 -1
- package/dist/dts/internal/data-grid-overlay-editor/private/number-overlay-editor.d.ts +0 -1
- package/dist/dts/internal/data-grid-overlay-editor/private/uri-overlay-editor-style.d.ts +0 -1
- package/dist/dts/internal/data-grid-overlay-editor/private/uri-overlay-editor.d.ts +0 -1
- package/dist/dts/internal/data-grid-overlay-editor/use-stay-on-screen.d.ts +0 -1
- package/dist/dts/internal/data-grid-search/data-grid-search-style.d.ts +0 -1
- package/dist/dts/internal/data-grid-search/data-grid-search.d.ts +0 -1
- package/dist/dts/internal/growing-entry/growing-entry-style.d.ts +0 -1
- package/dist/dts/internal/growing-entry/growing-entry.d.ts +0 -1
- package/dist/dts/internal/markdown-div/markdown-div.d.ts +0 -1
- package/dist/dts/internal/markdown-div/private/markdown-container.d.ts +0 -1
- package/dist/dts/internal/scrolling-data-grid/infinite-scroller.d.ts +0 -1
- package/dist/dts/internal/scrolling-data-grid/scrolling-data-grid.d.ts +0 -1
- package/dist/dts/internal/scrolling-data-grid/use-kinetic-scroll.d.ts +0 -1
- package/dist/esm/data-editor/data-editor.js +40 -7
- package/dist/esm/data-editor/data-editor.js.map +1 -1
- package/dist/esm/internal/data-editor-container/data-grid-container.css +1 -0
- package/dist/esm/internal/data-editor-container/data-grid-container.js +25 -30
- package/dist/esm/internal/data-grid/data-grid.js +7 -8
- package/dist/esm/internal/data-grid/data-grid.js.map +1 -1
- package/dist/esm/internal/data-grid/render/data-grid-lib.js +25 -7
- package/dist/esm/internal/data-grid/render/data-grid-lib.js.map +1 -1
- package/dist/esm/internal/data-grid/render/data-grid-render.header.js +32 -7
- package/dist/esm/internal/data-grid/render/data-grid-render.header.js.map +1 -1
- package/dist/esm/internal/data-grid/render/data-grid-render.js +14 -6
- package/dist/esm/internal/data-grid/render/data-grid-render.js.map +1 -1
- package/dist/esm/internal/data-grid-overlay-editor/data-grid-overlay-editor-style.css +1 -0
- package/dist/esm/internal/data-grid-overlay-editor/data-grid-overlay-editor-style.js +19 -75
- package/dist/esm/internal/data-grid-overlay-editor/private/bubbles-overlay-editor-style.css +1 -0
- package/dist/esm/internal/data-grid-overlay-editor/private/bubbles-overlay-editor-style.js +5 -32
- package/dist/esm/internal/data-grid-overlay-editor/private/drilldown-overlay-editor.css +1 -0
- package/dist/esm/internal/data-grid-overlay-editor/private/drilldown-overlay-editor.js +15 -45
- package/dist/esm/internal/data-grid-overlay-editor/private/image-overlay-editor-style.css +1 -0
- package/dist/esm/internal/data-grid-overlay-editor/private/image-overlay-editor-style.js +5 -54
- package/dist/esm/internal/data-grid-overlay-editor/private/markdown-overlay-editor-style.css +1 -0
- package/dist/esm/internal/data-grid-overlay-editor/private/markdown-overlay-editor-style.js +9 -74
- package/dist/esm/internal/data-grid-overlay-editor/private/number-overlay-editor-style.css +1 -0
- package/dist/esm/internal/data-grid-overlay-editor/private/number-overlay-editor-style.js +5 -13
- package/dist/esm/internal/data-grid-overlay-editor/private/uri-overlay-editor-style.css +1 -0
- package/dist/esm/internal/data-grid-overlay-editor/private/uri-overlay-editor-style.js +5 -51
- package/dist/esm/internal/data-grid-search/data-grid-search-style.css +1 -0
- package/dist/esm/internal/data-grid-search/data-grid-search-style.js +5 -94
- package/dist/esm/internal/growing-entry/growing-entry-style.css +3 -0
- package/dist/esm/internal/growing-entry/growing-entry-style.js +15 -58
- package/dist/esm/internal/markdown-div/private/markdown-container.css +1 -0
- package/dist/esm/internal/markdown-div/private/markdown-container.js +5 -17
- package/dist/esm/internal/scrolling-data-grid/infinite-scroller.css +1 -0
- package/dist/esm/internal/scrolling-data-grid/infinite-scroller.js +233 -231
- package/dist/index.css +12 -0
- package/package.json +1 -1
- package/src/data-editor/data-editor.tsx +50 -7
- package/src/docs/examples/custom-group-header.stories.tsx +41 -11
- package/src/internal/data-grid/data-grid.tsx +8 -9
- package/src/internal/data-grid/event-args.ts +1 -1
- package/src/internal/data-grid/render/data-grid-lib.ts +24 -6
- package/src/internal/data-grid/render/data-grid-render.header.ts +34 -5
- package/src/internal/data-grid/render/data-grid-render.ts +13 -6
- package/test/data-editor.test.tsx +21 -13
- package/test/data-grid.test.tsx +14 -2
|
@@ -7,9 +7,10 @@ import {
|
|
|
7
7
|
useMockDataGenerator,
|
|
8
8
|
defaultProps,
|
|
9
9
|
} from "../../data-editor/stories/utils.js";
|
|
10
|
-
import type { DrawGroupHeaderCallback } from "../../internal/data-grid/data-grid-types.js";
|
|
10
|
+
import type { DrawGroupHeaderCallback, GridSelection } from "../../internal/data-grid/data-grid-types.js";
|
|
11
11
|
import { GridColumnIcon } from "../../internal/data-grid/data-grid-types.js";
|
|
12
12
|
import { SimpleThemeWrapper } from "../../stories/story-utils.js";
|
|
13
|
+
import { emptyGridSelection } from "../../data-editor/data-editor.js";
|
|
13
14
|
|
|
14
15
|
const COMPOSITE_DESTINATION_OVER = "destination-over";
|
|
15
16
|
const COMPOSITE_SOURCE_OVER = "source-over";
|
|
@@ -66,7 +67,8 @@ export const CustomGroupHeaderDrawing: React.VFC = () => {
|
|
|
66
67
|
});
|
|
67
68
|
|
|
68
69
|
const drawGroupHeader: DrawGroupHeaderCallback = React.useCallback(args => {
|
|
69
|
-
const { ctx, groupName, level, span, rect, theme, isSelected, isHovered } = args;
|
|
70
|
+
const { ctx, groupName, level, span, rect, theme, isSelected, isHovered, } = args;
|
|
71
|
+
console.log(args);
|
|
70
72
|
|
|
71
73
|
// First draw default to get icons and actions, but we'll draw over the background
|
|
72
74
|
// Save the context state before default drawing
|
|
@@ -96,7 +98,7 @@ export const CustomGroupHeaderDrawing: React.VFC = () => {
|
|
|
96
98
|
// Use composite operation to draw background behind existing content
|
|
97
99
|
ctx.globalCompositeOperation = COMPOSITE_DESTINATION_OVER;
|
|
98
100
|
ctx.fillStyle = gradient;
|
|
99
|
-
ctx.fill();
|
|
101
|
+
// ctx.fill();
|
|
100
102
|
ctx.globalCompositeOperation = COMPOSITE_SOURCE_OVER;
|
|
101
103
|
|
|
102
104
|
// Draw border
|
|
@@ -107,7 +109,7 @@ export const CustomGroupHeaderDrawing: React.VFC = () => {
|
|
|
107
109
|
|
|
108
110
|
// Draw custom text with shadow effect
|
|
109
111
|
if (groupName !== "") {
|
|
110
|
-
ctx.fillStyle = isSelected ? theme.textHeaderSelected : theme.textHeader;
|
|
112
|
+
// ctx.fillStyle = isSelected ? theme.textHeaderSelected : theme.textHeader;
|
|
111
113
|
ctx.font = `bold ${14 + level * 2}px ${theme.fontFamily}`;
|
|
112
114
|
ctx.textAlign = "left";
|
|
113
115
|
ctx.textBaseline = "middle";
|
|
@@ -119,6 +121,7 @@ export const CustomGroupHeaderDrawing: React.VFC = () => {
|
|
|
119
121
|
ctx.shadowOffsetY = 1;
|
|
120
122
|
|
|
121
123
|
const padding = 12 + level * 4;
|
|
124
|
+
|
|
122
125
|
ctx.fillText(groupName, rect.x + padding, rect.y + rect.height / 2);
|
|
123
126
|
|
|
124
127
|
// Reset shadow
|
|
@@ -130,7 +133,7 @@ export const CustomGroupHeaderDrawing: React.VFC = () => {
|
|
|
130
133
|
// Draw span indicator (number of columns in group)
|
|
131
134
|
const spanText = `(${span[1] - span[0] + 1} cols)`;
|
|
132
135
|
ctx.font = `${10}px ${theme.fontFamily}`;
|
|
133
|
-
ctx.fillStyle = isSelected ? theme.textHeaderSelected : (theme.textGroupHeader ?? theme.textHeader);
|
|
136
|
+
// ctx.fillStyle = isSelected ? theme.textHeaderSelected : (theme.textGroupHeader ?? theme.textHeader);
|
|
134
137
|
ctx.globalAlpha = 0.7;
|
|
135
138
|
const textWidth = ctx.measureText(groupName).width;
|
|
136
139
|
ctx.fillText(spanText, rect.x + padding + textWidth + 8, rect.y + rect.height / 2);
|
|
@@ -138,16 +141,16 @@ export const CustomGroupHeaderDrawing: React.VFC = () => {
|
|
|
138
141
|
}
|
|
139
142
|
|
|
140
143
|
// Draw level indicator badge in top-right corner
|
|
141
|
-
ctx.fillStyle = isSelected ? theme.accentColor : theme.bgHeader;
|
|
144
|
+
// ctx.fillStyle = isSelected ? theme.accentColor : theme.bgHeader;
|
|
142
145
|
ctx.beginPath();
|
|
143
146
|
const badgeSize = 20;
|
|
144
147
|
const badgePadding = 4;
|
|
145
148
|
const badgeX = rect.x + rect.width - badgeSize - badgePadding;
|
|
146
149
|
const badgeY = rect.y + badgePadding;
|
|
147
150
|
ctx.arc(badgeX + badgeSize / 2, badgeY + badgeSize / 2, badgeSize / 2, 0, Math.PI * 2);
|
|
148
|
-
ctx.fill();
|
|
151
|
+
// ctx.fill();
|
|
149
152
|
|
|
150
|
-
ctx.fillStyle = theme.textHeader;
|
|
153
|
+
// ctx.fillStyle = theme.textHeader;
|
|
151
154
|
ctx.font = `bold ${10}px ${theme.fontFamily}`;
|
|
152
155
|
ctx.textAlign = "center";
|
|
153
156
|
ctx.textBaseline = "middle";
|
|
@@ -155,6 +158,8 @@ export const CustomGroupHeaderDrawing: React.VFC = () => {
|
|
|
155
158
|
|
|
156
159
|
ctx.restore();
|
|
157
160
|
}, []);
|
|
161
|
+
const [sel, setSel] = React.useState<GridSelection>(emptyGridSelection);
|
|
162
|
+
|
|
158
163
|
|
|
159
164
|
return (
|
|
160
165
|
<DataEditor
|
|
@@ -166,9 +171,34 @@ export const CustomGroupHeaderDrawing: React.VFC = () => {
|
|
|
166
171
|
name: g,
|
|
167
172
|
icon: g === "" ? undefined : GridColumnIcon.HeaderCode,
|
|
168
173
|
})}
|
|
174
|
+
// freezeColumns={3}
|
|
169
175
|
groupHeaderHeight={[36, 32, 30, 28]} // Four different heights for four levels
|
|
170
|
-
drawGroupHeader={drawGroupHeader}
|
|
176
|
+
// drawGroupHeader={drawGroupHeader}
|
|
177
|
+
drawHeader={(args,draw) => {
|
|
178
|
+
console.log(args);
|
|
179
|
+
draw();
|
|
180
|
+
}}
|
|
171
181
|
rowMarkers="both"
|
|
182
|
+
gridSelection={sel}
|
|
183
|
+
onGridSelectionChange={(args) => {
|
|
184
|
+
setSel(args)
|
|
185
|
+
console.log('onGridSelectionChange',args);
|
|
186
|
+
}}
|
|
187
|
+
onGroupHeaderClicked={(args) => {
|
|
188
|
+
console.log('onGroupHeaderClicked',args);
|
|
189
|
+
}}
|
|
190
|
+
onMouseMove={(args) => {
|
|
191
|
+
if(args.kind === "group-header") {
|
|
192
|
+
|
|
193
|
+
// console.log('onMouseMove',args);
|
|
194
|
+
}
|
|
195
|
+
}}
|
|
196
|
+
onCellClicked={(args) => {
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
// console.log('onCellClicked',args);
|
|
200
|
+
|
|
201
|
+
}}
|
|
172
202
|
/>
|
|
173
203
|
);
|
|
174
204
|
};
|
|
@@ -190,8 +220,8 @@ export const MinimalGroupHeader: React.VFC = () => {
|
|
|
190
220
|
});
|
|
191
221
|
|
|
192
222
|
const drawGroupHeader: DrawGroupHeaderCallback = React.useCallback(args => {
|
|
193
|
-
const { ctx, rect, theme, isSelected, isHovered } = args;
|
|
194
|
-
|
|
223
|
+
const { ctx, rect, theme, isSelected, isHovered, groupName } = args;
|
|
224
|
+
|
|
195
225
|
// Call default drawing first
|
|
196
226
|
ctx.save();
|
|
197
227
|
// draw();
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
rectBottomRight,
|
|
10
10
|
useMappedColumns,
|
|
11
11
|
} from "./render/data-grid-lib.js";
|
|
12
|
+
import { getGroupLevels, getTotalGroupHeaderHeight } from "./render/data-grid-render.walk.js";
|
|
12
13
|
import {
|
|
13
14
|
GridCellKind,
|
|
14
15
|
type Rectangle,
|
|
@@ -445,13 +446,6 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,
|
|
|
445
446
|
}),
|
|
446
447
|
[headerIcons]
|
|
447
448
|
);
|
|
448
|
-
const groupHeights = enableGroups
|
|
449
|
-
? (Array.isArray(groupHeaderHeight)
|
|
450
|
-
? groupHeaderHeight.reduce((sum, h) => sum + h, 0)
|
|
451
|
-
: groupHeaderHeight)
|
|
452
|
-
: 0;
|
|
453
|
-
const totalHeaderHeight = headerHeight + groupHeights;
|
|
454
|
-
|
|
455
449
|
const scrollingStopRef = React.useRef(-1);
|
|
456
450
|
const enableFirefoxRescaling = (experimental?.enableFirefoxRescaling ?? false) && browserIsFirefox.value;
|
|
457
451
|
const enableSafariRescaling = (experimental?.enableSafariRescaling ?? false) && browserIsSafari.value;
|
|
@@ -469,6 +463,9 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,
|
|
|
469
463
|
}, [cellYOffset, cellXOffset, translateX, translateY, enableFirefoxRescaling, enableSafariRescaling]);
|
|
470
464
|
|
|
471
465
|
const mappedColumns = useMappedColumns(columns, freezeColumns);
|
|
466
|
+
const groupHeaderLevels = enableGroups ? getGroupLevels(mappedColumns) : 0;
|
|
467
|
+
const totalGroupHeaderHeight = enableGroups ? getTotalGroupHeaderHeight(groupHeaderHeight, mappedColumns) : 0;
|
|
468
|
+
const totalHeaderHeight = headerHeight + totalGroupHeaderHeight;
|
|
472
469
|
const stickyX = React.useMemo(
|
|
473
470
|
() => (fixedShadowX ? getStickyWidth(mappedColumns, dragAndDropState) : 0),
|
|
474
471
|
[mappedColumns, dragAndDropState, fixedShadowX]
|
|
@@ -578,7 +575,8 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,
|
|
|
578
575
|
rowHeight,
|
|
579
576
|
cellYOffset,
|
|
580
577
|
translateY,
|
|
581
|
-
freezeTrailingRows
|
|
578
|
+
freezeTrailingRows,
|
|
579
|
+
groupHeaderLevels
|
|
582
580
|
);
|
|
583
581
|
|
|
584
582
|
const shiftKey = ev?.shiftKey === true;
|
|
@@ -741,6 +739,7 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,
|
|
|
741
739
|
enableGroups,
|
|
742
740
|
headerHeight,
|
|
743
741
|
groupHeaderHeight,
|
|
742
|
+
groupHeaderLevels,
|
|
744
743
|
rows,
|
|
745
744
|
rowHeight,
|
|
746
745
|
cellYOffset,
|
|
@@ -987,7 +986,7 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,
|
|
|
987
986
|
hCol >= 0 &&
|
|
988
987
|
hCol < mappedColumns.length &&
|
|
989
988
|
mappedColumns[hCol].headerRowMarkerDisabled !== true;
|
|
990
|
-
const groupHeaderHovered = hCol !== undefined && hRow
|
|
989
|
+
const groupHeaderHovered = hCol !== undefined && hRow !== undefined && hRow <= -2;
|
|
991
990
|
let clickableInnerCellHovered = false;
|
|
992
991
|
let editableBoolHovered = false;
|
|
993
992
|
let cursorOverride: React.CSSProperties["cursor"] | undefined = drawCursorOverride;
|
|
@@ -42,7 +42,7 @@ export const groupHeaderKind = "group-header" as const;
|
|
|
42
42
|
/** @category Types */
|
|
43
43
|
export interface GridMouseGroupHeaderEventArgs extends BaseGridMouseEventArgs, PositionableMouseEventArgs {
|
|
44
44
|
readonly kind: typeof groupHeaderKind;
|
|
45
|
-
readonly location:
|
|
45
|
+
readonly location: Item;
|
|
46
46
|
readonly bounds: Rectangle;
|
|
47
47
|
readonly group: string;
|
|
48
48
|
}
|
|
@@ -293,13 +293,31 @@ export function getRowIndexForY(
|
|
|
293
293
|
rowHeight: number | ((index: number) => number),
|
|
294
294
|
cellYOffset: number,
|
|
295
295
|
translateY: number,
|
|
296
|
-
freezeTrailingRows: number
|
|
296
|
+
freezeTrailingRows: number,
|
|
297
|
+
groupHeaderLevels?: number
|
|
297
298
|
): number | undefined {
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
299
|
+
const groupHeightsArray = Array.isArray(groupHeaderHeight) ? groupHeaderHeight : undefined;
|
|
300
|
+
const groupHeaderHeightValue = typeof groupHeaderHeight === "number" ? groupHeaderHeight : undefined;
|
|
301
|
+
const levels = groupHeightsArray?.length ?? (groupHeaderLevels ?? (hasGroups ? 1 : 0));
|
|
302
|
+
const groupHeights = hasGroups
|
|
303
|
+
? (groupHeightsArray !== undefined
|
|
304
|
+
? groupHeightsArray.reduce((sum, h) => sum + h, 0)
|
|
305
|
+
: (levels > 0 && groupHeaderHeightValue !== undefined ? groupHeaderHeightValue * levels : 0))
|
|
306
|
+
: 0;
|
|
301
307
|
const totalHeaderHeight = headerHeight + groupHeights;
|
|
302
|
-
if (hasGroups && targetY <= groupHeights)
|
|
308
|
+
if (hasGroups && levels > 0 && targetY <= groupHeights) {
|
|
309
|
+
if (groupHeightsArray !== undefined) {
|
|
310
|
+
let yOffset = 0;
|
|
311
|
+
for (let level = 0; level < levels; level++) {
|
|
312
|
+
yOffset += groupHeightsArray[level] ?? groupHeightsArray[0] ?? 0;
|
|
313
|
+
if (targetY <= yOffset) return -2 - level;
|
|
314
|
+
}
|
|
315
|
+
return -2 - (levels - 1);
|
|
316
|
+
}
|
|
317
|
+
if (groupHeaderHeightValue === undefined || groupHeaderHeightValue <= 0) return -2;
|
|
318
|
+
const groupLevel = Math.min(levels - 1, Math.max(0, Math.floor(targetY / groupHeaderHeightValue)));
|
|
319
|
+
return -2 - groupLevel;
|
|
320
|
+
}
|
|
303
321
|
if (targetY <= totalHeaderHeight) return -1;
|
|
304
322
|
|
|
305
323
|
let y = height;
|
|
@@ -805,7 +823,7 @@ export function computeBounds(
|
|
|
805
823
|
height: 0,
|
|
806
824
|
};
|
|
807
825
|
|
|
808
|
-
if (col >= mappedColumns.length || row >= rows ||
|
|
826
|
+
if (col >= mappedColumns.length || row >= rows || col < 0) {
|
|
809
827
|
return result;
|
|
810
828
|
}
|
|
811
829
|
|
|
@@ -97,11 +97,15 @@ export function drawGridHeaders(
|
|
|
97
97
|
const bgFillStyle = selected ? theme.accentColor : hasSelectedCell ? theme.bgHeaderHasFocus : theme.bgHeader;
|
|
98
98
|
|
|
99
99
|
const y = enableGroups ? totalGroupHeaderHeight : 0;
|
|
100
|
+
const isFirstSelected = selected && selection.columns.first() === c.sourceIndex;
|
|
100
101
|
const xOffset = c.sourceIndex === 0 ? 0 : 1;
|
|
101
102
|
|
|
102
103
|
if (selected) {
|
|
103
104
|
ctx.fillStyle = bgFillStyle;
|
|
104
105
|
ctx.fillRect(x + xOffset, y, c.width - xOffset, headerHeight);
|
|
106
|
+
if (isFirstSelected) {
|
|
107
|
+
ctx.fillRect(x, y, 1, headerHeight);
|
|
108
|
+
}
|
|
105
109
|
} else if (hasSelectedCell || hover > 0) {
|
|
106
110
|
ctx.beginPath();
|
|
107
111
|
ctx.rect(x + xOffset, y, c.width - xOffset, headerHeight);
|
|
@@ -227,6 +231,7 @@ function drawGroupHeaderInner(
|
|
|
227
231
|
span: readonly [number, number],
|
|
228
232
|
isSelected: boolean,
|
|
229
233
|
isHovered: boolean,
|
|
234
|
+
hoverAmount: number,
|
|
230
235
|
theme: FullTheme,
|
|
231
236
|
groupTheme: FullTheme,
|
|
232
237
|
group: GroupDetails,
|
|
@@ -243,7 +248,13 @@ function drawGroupHeaderInner(
|
|
|
243
248
|
|
|
244
249
|
if (fillColor !== theme.bgHeader) {
|
|
245
250
|
ctx.fillStyle = fillColor;
|
|
246
|
-
|
|
251
|
+
if (hoverAmount > 0) {
|
|
252
|
+
ctx.globalAlpha = hoverAmount;
|
|
253
|
+
ctx.fillRect(x, y + 1, width, height - 1);
|
|
254
|
+
ctx.globalAlpha = 1;
|
|
255
|
+
} else {
|
|
256
|
+
ctx.fillRect(x, y, width, height);
|
|
257
|
+
}
|
|
247
258
|
}
|
|
248
259
|
|
|
249
260
|
ctx.fillStyle = groupTheme.textGroupHeader ?? groupTheme.textHeader;
|
|
@@ -335,6 +346,15 @@ function drawGroupLevel(
|
|
|
335
346
|
const hPosY = hovered?.[1]?.[1];
|
|
336
347
|
// hRow: -2 is group header, we use -2 - level for multi-level
|
|
337
348
|
const targetRow = -2 - level;
|
|
349
|
+
const selectionRow = selection?.current?.cell[1];
|
|
350
|
+
const selectionLevel = selectionRow !== undefined && selectionRow <= -2 ? -2 - selectionRow : undefined;
|
|
351
|
+
const selectionSpan =
|
|
352
|
+
selection?.current === undefined || selectionLevel === undefined
|
|
353
|
+
? undefined
|
|
354
|
+
: ([
|
|
355
|
+
selection.current.range.x,
|
|
356
|
+
selection.current.range.x + selection.current.range.width - 1,
|
|
357
|
+
] as const);
|
|
338
358
|
|
|
339
359
|
let finalX = 0;
|
|
340
360
|
walkGroups(effectiveCols, width, translateX, groupHeaderHeight, level, (span, groupName, x, y, w, h) => {
|
|
@@ -356,13 +376,20 @@ function drawGroupLevel(
|
|
|
356
376
|
const group = getGroupDetails(groupName);
|
|
357
377
|
const groupTheme =
|
|
358
378
|
group?.overrideTheme === undefined ? theme : mergeAndRealizeTheme(theme, group.overrideTheme);
|
|
359
|
-
const isHovered = hRow === targetRow && hCol !== undefined && hCol >= span[0] && hCol <= span[1];
|
|
360
|
-
|
|
361
379
|
// Check if all columns in this group span are selected
|
|
362
380
|
let isSelected = false;
|
|
363
381
|
if (selection !== undefined) {
|
|
364
|
-
|
|
382
|
+
const selectionMatchesLevel = selectionRow !== undefined && targetRow <= selectionRow;
|
|
383
|
+
const spanInSelection =
|
|
384
|
+
selectionSpan !== undefined && span[0] >= selectionSpan[0] && span[1] <= selectionSpan[1];
|
|
385
|
+
isSelected =
|
|
386
|
+
selectionMatchesLevel && spanInSelection && selection.columns.hasAll([span[0], span[1] + 1]);
|
|
365
387
|
}
|
|
388
|
+
const isHovered = hRow === targetRow && hCol !== undefined && hCol >= span[0] && hCol <= span[1];
|
|
389
|
+
const hoverAmount =
|
|
390
|
+
isSelected || !isHovered
|
|
391
|
+
? 0
|
|
392
|
+
: (_hoverValues.find(s => s.item[0] === hCol && s.item[1] === targetRow)?.hoverAmount ?? 0);
|
|
366
393
|
|
|
367
394
|
if (drawGroupHeaderCallback !== undefined) {
|
|
368
395
|
drawGroupHeaderCallback(
|
|
@@ -372,7 +399,7 @@ function drawGroupLevel(
|
|
|
372
399
|
level,
|
|
373
400
|
span,
|
|
374
401
|
theme: groupTheme,
|
|
375
|
-
rect: { x, y: y + yOffset, width: w, height: h },
|
|
402
|
+
rect: { x: x + 0.5, y: y + yOffset, width: w, height: h },
|
|
376
403
|
isSelected,
|
|
377
404
|
isHovered,
|
|
378
405
|
spriteManager,
|
|
@@ -391,6 +418,7 @@ function drawGroupLevel(
|
|
|
391
418
|
span,
|
|
392
419
|
isSelected,
|
|
393
420
|
isHovered,
|
|
421
|
+
hoverAmount,
|
|
394
422
|
theme,
|
|
395
423
|
groupTheme,
|
|
396
424
|
group,
|
|
@@ -411,6 +439,7 @@ function drawGroupLevel(
|
|
|
411
439
|
span,
|
|
412
440
|
isSelected,
|
|
413
441
|
isHovered,
|
|
442
|
+
hoverAmount,
|
|
414
443
|
theme,
|
|
415
444
|
groupTheme,
|
|
416
445
|
group,
|
|
@@ -50,13 +50,16 @@ function clipHeaderDamage(
|
|
|
50
50
|
? groupHeaderHeight
|
|
51
51
|
: Array.from({ length: levels }, () => groupHeaderHeight);
|
|
52
52
|
|
|
53
|
+
let currentY = 0;
|
|
53
54
|
for (let level = 0; level < levels; level++) {
|
|
55
|
+
const levelHeight = heights[level] ?? heights[0] ?? 0;
|
|
56
|
+
if (levelHeight <= 0) continue;
|
|
54
57
|
const targetRow = -2 - level;
|
|
55
58
|
walkGroups(
|
|
56
59
|
effectiveColumns,
|
|
57
60
|
width,
|
|
58
61
|
translateX,
|
|
59
|
-
|
|
62
|
+
levelHeight,
|
|
60
63
|
level,
|
|
61
64
|
(span, _group, x, y, w, h) => {
|
|
62
65
|
const hasItemInSpan = damage.hasItemInRectangle({
|
|
@@ -66,10 +69,11 @@ function clipHeaderDamage(
|
|
|
66
69
|
height: 1,
|
|
67
70
|
});
|
|
68
71
|
if (hasItemInSpan) {
|
|
69
|
-
ctx.rect(x, y, w, h);
|
|
72
|
+
ctx.rect(x, y + currentY, w, h);
|
|
70
73
|
}
|
|
71
74
|
}
|
|
72
75
|
);
|
|
76
|
+
currentY += levelHeight;
|
|
73
77
|
}
|
|
74
78
|
|
|
75
79
|
walkColumns(
|
|
@@ -394,12 +398,15 @@ export function drawGrid(arg: DrawGridArg, lastArg: DrawGridArg | undefined) {
|
|
|
394
398
|
// handle damage updates by directly drawing to the target to avoid large blits
|
|
395
399
|
if (damage !== undefined) {
|
|
396
400
|
const viewRegionWidth = effectiveCols[effectiveCols.length - 1].sourceIndex + 1;
|
|
401
|
+
const groupHeaderLevels = enableGroups ? getGroupLevels(mappedColumns) : 0;
|
|
402
|
+
const headerRegionRowStart = -1 - groupHeaderLevels;
|
|
403
|
+
const headerRegionHeight = groupHeaderLevels + 1;
|
|
397
404
|
const damageInView = damage.hasItemInRegion([
|
|
398
405
|
{
|
|
399
406
|
x: cellXOffset,
|
|
400
|
-
y:
|
|
407
|
+
y: headerRegionRowStart,
|
|
401
408
|
width: viewRegionWidth,
|
|
402
|
-
height:
|
|
409
|
+
height: headerRegionHeight,
|
|
403
410
|
},
|
|
404
411
|
{
|
|
405
412
|
x: cellXOffset,
|
|
@@ -415,9 +422,9 @@ export function drawGrid(arg: DrawGridArg, lastArg: DrawGridArg | undefined) {
|
|
|
415
422
|
},
|
|
416
423
|
{
|
|
417
424
|
x: 0,
|
|
418
|
-
y:
|
|
425
|
+
y: headerRegionRowStart,
|
|
419
426
|
width: freezeColumns,
|
|
420
|
-
height:
|
|
427
|
+
height: headerRegionHeight,
|
|
421
428
|
},
|
|
422
429
|
{
|
|
423
430
|
x: cellXOffset,
|
|
@@ -966,10 +966,13 @@ describe("data-editor", () => {
|
|
|
966
966
|
});
|
|
967
967
|
|
|
968
968
|
expect(spy).toHaveBeenCalledTimes(1);
|
|
969
|
-
expect(spy).toHaveBeenCalledWith(
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
969
|
+
expect(spy).toHaveBeenCalledWith(
|
|
970
|
+
expect.objectContaining({
|
|
971
|
+
columns: CompactSelection.fromSingleSelection([0, 11]),
|
|
972
|
+
rows: CompactSelection.empty(),
|
|
973
|
+
current: expect.objectContaining({ cell: [0, -2] }),
|
|
974
|
+
})
|
|
975
|
+
);
|
|
973
976
|
|
|
974
977
|
spy.mockClear();
|
|
975
978
|
|
|
@@ -980,10 +983,13 @@ describe("data-editor", () => {
|
|
|
980
983
|
});
|
|
981
984
|
|
|
982
985
|
expect(spy).toHaveBeenCalled();
|
|
983
|
-
expect(spy).toHaveBeenCalledWith(
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
986
|
+
expect(spy).toHaveBeenCalledWith(
|
|
987
|
+
expect.objectContaining({
|
|
988
|
+
columns: CompactSelection.empty(),
|
|
989
|
+
rows: CompactSelection.empty(),
|
|
990
|
+
current: undefined,
|
|
991
|
+
})
|
|
992
|
+
);
|
|
987
993
|
|
|
988
994
|
spy.mockClear();
|
|
989
995
|
|
|
@@ -994,11 +1000,13 @@ describe("data-editor", () => {
|
|
|
994
1000
|
});
|
|
995
1001
|
|
|
996
1002
|
expect(spy).toHaveBeenCalled();
|
|
997
|
-
expect(spy).toHaveBeenCalledWith(
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1003
|
+
expect(spy).toHaveBeenCalledWith(
|
|
1004
|
+
expect.objectContaining({
|
|
1005
|
+
rows: CompactSelection.empty(),
|
|
1006
|
+
columns: CompactSelection.fromSingleSelection([0, 11]),
|
|
1007
|
+
current: expect.objectContaining({ cell: [0, -2] }),
|
|
1008
|
+
})
|
|
1009
|
+
);
|
|
1002
1010
|
});
|
|
1003
1011
|
|
|
1004
1012
|
test("Rename group header shows", async () => {
|
package/test/data-grid.test.tsx
CHANGED
|
@@ -305,9 +305,17 @@ describe("data-grid", () => {
|
|
|
305
305
|
|
|
306
306
|
test("Header hovered when scrolled", () => {
|
|
307
307
|
const spy = vi.fn();
|
|
308
|
+
const groupedColumns = basicProps.columns.map(col => ({ ...col, group: "A" }));
|
|
308
309
|
|
|
309
310
|
render(
|
|
310
|
-
<DataGrid
|
|
311
|
+
<DataGrid
|
|
312
|
+
{...basicProps}
|
|
313
|
+
columns={groupedColumns}
|
|
314
|
+
groupHeaderHeight={32}
|
|
315
|
+
enableGroups={true}
|
|
316
|
+
cellYOffset={10}
|
|
317
|
+
onItemHovered={spy}
|
|
318
|
+
/>
|
|
311
319
|
);
|
|
312
320
|
|
|
313
321
|
const el = screen.getByTestId(dataGridCanvasId);
|
|
@@ -327,7 +335,11 @@ describe("data-grid", () => {
|
|
|
327
335
|
test("Group header hovered", () => {
|
|
328
336
|
const spy = vi.fn();
|
|
329
337
|
|
|
330
|
-
|
|
338
|
+
const groupedColumns = basicProps.columns.map(col => ({ ...col, group: "A" }));
|
|
339
|
+
// TODO old test
|
|
340
|
+
//render(<DataGrid {...basicProps} onItemHovered={spy} enableGroups={true} groupHeaderHeight={28} />);
|
|
341
|
+
|
|
342
|
+
render(<DataGrid {...basicProps} columns={groupedColumns} onItemHovered={spy} enableGroups={true} groupHeaderHeight={28} />);
|
|
331
343
|
|
|
332
344
|
const el = screen.getByTestId(dataGridCanvasId);
|
|
333
345
|
fireEvent.pointerMove(el, {
|