Skip to content

Commit

Permalink
Fix row theme and column theme cutting off when entering into blank r…
Browse files Browse the repository at this point in the history
…egion of Grid
  • Loading branch information
jassmith committed Jan 24, 2024
1 parent 904cb33 commit 24d080a
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 28 deletions.
7 changes: 6 additions & 1 deletion packages/core/src/common/styles.ts
@@ -1,4 +1,5 @@
import React from "react";
import { blend } from "../internal/data-grid/color-parser.js";

// theme variable precidence

Expand Down Expand Up @@ -159,7 +160,11 @@ export function mergeAndRealizeTheme(theme: Theme, ...overlays: Partial<Theme |
for (const key in overlay) {
// eslint-disable-next-line no-prototype-builtins
if (overlay.hasOwnProperty(key)) {
merged[key] = (overlay as any)[key];
if (key === "bgCell") {
merged[key] = blend(overlay[key] as string, merged[key]);
} else {
merged[key] = (overlay as any)[key];
}
}
}
}
Expand Down
30 changes: 21 additions & 9 deletions packages/core/src/docs/examples/theme-per-row.stories.tsx
Expand Up @@ -35,27 +35,39 @@ export default {
export const ThemePerRow: React.VFC = () => {
const { cols, getCellContent, onColumnResize, setCellValue } = useMockDataGenerator(5);

const realCols = React.useMemo(() => {
const c = [...cols];
c[3] = {
...c[3],
themeOverride: {
bgCell: "#d6fafd",
},
};
return c;
}, [cols]);

return (
<DataEditor
{...defaultProps}
getCellContent={getCellContent}
columns={cols}
trailingRowOptions={{
sticky: true,
tint: true,
}}
onRowAppended={() => undefined}
columns={realCols}
height="100%"
// trailingRowOptions={{
// sticky: true,
// tint: true,
// }}
// onRowAppended={() => undefined}
getRowThemeOverride={i =>
i % 2 === 0
? undefined
: {
bgCell: "#f0f8ff",
borderColor: "#3f90e0",
bgCell: "#e0f0ff88",
// borderColor: "#3f90e0",
}
}
onCellEdited={setCellValue}
onColumnResize={onColumnResize}
rows={1_000_000}
rows={10}
/>
);
};
146 changes: 129 additions & 17 deletions packages/core/src/internal/data-grid/render/data-grid-render.lines.ts
Expand Up @@ -146,6 +146,134 @@ export function overdrawStickyBoundaries(
}
}

const getMinMaxXY = (drawRegions: Rectangle[] | undefined, width: number, height: number) => {
let minX = 0;
let maxX = width;
let minY = 0;
let maxY = height;

if (drawRegions !== undefined && drawRegions.length > 0) {
minX = Number.MAX_SAFE_INTEGER;
minY = Number.MAX_SAFE_INTEGER;
maxX = Number.MIN_SAFE_INTEGER;
maxY = Number.MIN_SAFE_INTEGER;
for (const r of drawRegions) {
minX = Math.min(minX, r.x - 1);
maxX = Math.max(maxX, r.x + r.width + 1);
minY = Math.min(minY, r.y - 1);
maxY = Math.max(maxY, r.y + r.height + 1);
}
}

return { minX, maxX, minY, maxY };
};

export function drawExtraRowThemes(
ctx: CanvasRenderingContext2D,
effectiveCols: readonly MappedGridColumn[],
cellYOffset: number,
translateX: number,
translateY: number,
width: number,
height: number,
drawRegions: Rectangle[] | undefined,
totalHeaderHeight: number,
getRowHeight: (row: number) => number,
getRowThemeOverride: GetRowThemeCallback | undefined,
verticalBorder: (col: number) => boolean,
freezeTrailingRows: number,
rows: number,
theme: FullTheme
) {
const bgCell = theme.bgCell;

const { minX, maxX, minY, maxY } = getMinMaxXY(drawRegions, width, height);

const toDraw: { x: number; y: number; w: number; h: number; color: string }[] = [];

const freezeY = height - getFreezeTrailingHeight(rows, freezeTrailingRows, getRowHeight);

// row overflow
let y = totalHeaderHeight;
let row = cellYOffset;
let y2 = 0;
while (y + translateY < freezeY) {
const ty = y + translateY;
const rh = getRowHeight(row);
if (ty >= minY && ty <= maxY - 1) {
const rowTheme = getRowThemeOverride?.(row);
const rowThemeBgCell = rowTheme?.bgCell;
const needDraw = rowThemeBgCell !== undefined && rowThemeBgCell !== bgCell && row >= rows;
if (needDraw) {
toDraw.push({
x: minX,
y: ty,
w: maxX - minX,
h: rh,
color: rowThemeBgCell,
});
}
}

y += rh;
if (row < rows) y2 = y;
row++;
}

// column overflow
let x = 0;
const h = Math.min(freezeY, maxY) - y2;
if (h > 0) {
for (let index = 0; index < effectiveCols.length; index++) {
const c = effectiveCols[index];
if (c.width === 0) continue;
const tx = c.sticky ? x : x + translateX;
const colThemeBgCell = c.themeOverride?.bgCell;
if (
colThemeBgCell !== undefined &&
colThemeBgCell !== bgCell &&
tx >= minX &&
tx <= maxX &&
verticalBorder(index + 1)
) {
toDraw.push({
x: tx,
y: y2,
w: c.width,
h,
color: colThemeBgCell,
});
}

x += c.width;
}
}

if (toDraw.length === 0) return;

let color: string | undefined;
ctx.beginPath();
// render in reverse order because we computed and added the columns last, but they should actually be lower
// priority than the rows.
for (let i = toDraw.length - 1; i >= 0; i--) {
const r = toDraw[i];
if (color === undefined) {
color = r.color;
} else if (r.color !== color) {
ctx.fillStyle = color;
ctx.fill();
ctx.beginPath();
color = r.color;
}
ctx.rect(r.x, r.y, r.w, r.h);
}
if (color !== undefined) {
ctx.fillStyle = color;
ctx.fill();
}
ctx.beginPath();
}

// lines are effectively drawn on the top left edge of a cell.
export function drawGridLines(
ctx: CanvasRenderingContext2D,
Expand Down Expand Up @@ -179,23 +307,7 @@ export function drawGridLines(
const hColor = theme.horizontalBorderColor ?? theme.borderColor;
const vColor = theme.borderColor;

let minX = 0;
let maxX = width;
let minY = 0;
let maxY = height;

if (drawRegions !== undefined && drawRegions.length > 0) {
minX = Number.MAX_SAFE_INTEGER;
minY = Number.MAX_SAFE_INTEGER;
maxX = Number.MIN_SAFE_INTEGER;
maxY = Number.MIN_SAFE_INTEGER;
for (const r of drawRegions) {
minX = Math.min(minX, r.x - 1);
maxX = Math.max(maxX, r.x + r.width + 1);
minY = Math.min(minY, r.y - 1);
maxY = Math.max(maxY, r.y + r.height + 1);
}
}
const { minX, maxX, minY, maxY } = getMinMaxXY(drawRegions, width, height);

const toDraw: { x1: number; y1: number; x2: number; y2: number; color: string }[] = [];

Expand Down
20 changes: 19 additions & 1 deletion packages/core/src/internal/data-grid/render/data-grid-render.ts
Expand Up @@ -9,7 +9,7 @@ import type { DrawGridArg } from "./draw-grid-arg.js";
import { walkColumns, walkGroups, walkRowsInCol } from "./data-grid-render.walk.js";
import { drawCells } from "./data-grid-render.cells.js";
import { drawGridHeaders } from "./data-grid-render.header.js";
import { drawGridLines, overdrawStickyBoundaries, drawBlanks } from "./data-grid-render.lines.js";
import { drawGridLines, overdrawStickyBoundaries, drawBlanks, drawExtraRowThemes } from "./data-grid-render.lines.js";
import { blitLastFrame, blitResizedCol, computeCanBlit } from "./data-grid-render.blit.js";
import { drawHighlightRings, drawFocusRing, drawColumnResizeOutline } from "./data-grid.render.rings.js";

Expand Down Expand Up @@ -680,6 +680,24 @@ export function drawGrid(arg: DrawGridArg, lastArg: DrawGridArg | undefined) {
theme
);

drawExtraRowThemes(
targetCtx,
effectiveCols,
cellYOffset,
translateX,
translateY,
width,
height,
drawRegions,
totalHeaderHeight,
getRowHeight,
getRowThemeOverride,
verticalBorder,
freezeTrailingRows,
rows,
theme
);

drawGridLines(
targetCtx,
effectiveCols,
Expand Down

0 comments on commit 24d080a

Please sign in to comment.