Skip to content

Commit a1c07f1

Browse files
committed
feat: row col border lines
1 parent e7d8fce commit a1c07f1

File tree

6 files changed

+163
-15
lines changed

6 files changed

+163
-15
lines changed

packages/core/src/data-editor/data-editor.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ export interface DataEditorProps extends Props, Pick<DataGridSearchProps, "image
499499
readonly gridSelection?: GridSelection;
500500
/**
501501
* Emitted whenever the grid selection changes. Specifying
502-
* this function will make the grids selection controlled, so
502+
* this function will make the grid's selection controlled, so
503503
* so you will need to specify {@link gridSelection} as well. See
504504
* the "Controlled Selection" example for details.
505505
*
@@ -686,6 +686,22 @@ export interface DataEditorProps extends Props, Pick<DataGridSearchProps, "image
686686
* Allows overriding the default portal element.
687687
*/
688688
readonly portalElementRef?: React.RefObject<HTMLElement>;
689+
690+
/**
691+
* When true (default) draws accent-coloured grid lines around selected columns in the header. Set to false to
692+
* revert to the original behaviour where only the header background is accented.
693+
* @group Style
694+
* @defaultValue true
695+
*/
696+
readonly columnSelectionGridLines?: boolean;
697+
698+
/**
699+
* When true (default) draws accent-coloured grid lines around selected rows in the header. Set to false to
700+
* revert to the original behaviour where only the header background is accented.
701+
* @group Style
702+
* @defaultValue true
703+
*/
704+
readonly rowSelectionGridLines?: boolean;
689705
}
690706

691707
type ScrollToFn = (
@@ -892,6 +908,8 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
892908
scrollToActiveCell = true,
893909
drawFocusRing: drawFocusRingIn = true,
894910
portalElementRef,
911+
columnSelectionGridLines = true,
912+
rowSelectionGridLines = true,
895913
} = p;
896914

897915
const drawFocusRing = drawFocusRingIn === "no-editor" ? overlay === undefined : drawFocusRingIn;
@@ -4264,6 +4282,8 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
42644282
gridRef={gridRef}
42654283
getCellRenderer={getCellRenderer}
42664284
resizeIndicator={resizeIndicator}
4285+
columnSelectionGridLines={columnSelectionGridLines}
4286+
rowSelectionGridLines={rowSelectionGridLines}
42674287
/>
42684288
{renameGroupNode}
42694289
{overlay !== undefined && (
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import React from "react";
2+
import { DataEditorAll as DataEditor } from "../../data-editor-all.js";
3+
import {
4+
BeautifulWrapper,
5+
Description,
6+
MoreInfo,
7+
useMockDataGenerator,
8+
defaultProps,
9+
} from "../../data-editor/stories/utils.js";
10+
import { SimpleThemeWrapper } from "../../stories/story-utils.js";
11+
12+
export default {
13+
title: "Glide-Data-Grid/DataEditor Demos",
14+
15+
decorators: [
16+
(Story: React.ComponentType) => (
17+
<SimpleThemeWrapper>
18+
<BeautifulWrapper
19+
title="Column & Row Selection Grid Lines"
20+
description={
21+
<>
22+
<Description>
23+
Demonstrates the <code>columnSelectionGridLines</code> and
24+
<code>rowSelectionGridLines</code> props which control whether accent-coloured grid
25+
lines are drawn around selected columns and rows.
26+
</Description>
27+
<MoreInfo>
28+
Use the story controls to toggle the behaviours on and off.
29+
</MoreInfo>
30+
</>
31+
}>
32+
<Story />
33+
</BeautifulWrapper>
34+
</SimpleThemeWrapper>
35+
),
36+
],
37+
};
38+
39+
interface GridLineDemoProps {
40+
columnSelectionGridLines: boolean;
41+
rowSelectionGridLines: boolean;
42+
}
43+
44+
export const GridLineDemo: React.FC<GridLineDemoProps> = p => {
45+
const { cols, getCellContent } = useMockDataGenerator(10);
46+
47+
return (
48+
<DataEditor
49+
{...defaultProps}
50+
getCellContent={getCellContent}
51+
columns={cols}
52+
rows={1000}
53+
columnSelectionGridLines={p.columnSelectionGridLines}
54+
rowSelectionGridLines={p.rowSelectionGridLines}
55+
rowMarkers="both"
56+
/>
57+
);
58+
};
59+
60+
(GridLineDemo as any).args = {
61+
columnSelectionGridLines: true,
62+
rowSelectionGridLines: true,
63+
};
64+
65+
(GridLineDemo as any).argTypes = {
66+
columnSelectionGridLines: {
67+
control: {
68+
type: "boolean",
69+
},
70+
},
71+
rowSelectionGridLines: {
72+
control: {
73+
type: "boolean",
74+
},
75+
},
76+
};

packages/core/src/internal/data-grid/data-grid.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,18 @@ export interface DataGridProps {
307307
* @group Style
308308
*/
309309
readonly resizeIndicator: "full" | "header" | "none" | undefined;
310+
311+
/** Enables accent-coloured grid lines for selected columns in the header.
312+
* @defaultValue false
313+
* @group Style
314+
*/
315+
readonly columnSelectionGridLines?: boolean;
316+
317+
/** Enables accent-coloured grid lines for selected rows in the header.
318+
* @defaultValue false
319+
* @group Style
320+
*/
321+
readonly rowSelectionGridLines?: boolean;
310322
}
311323

312324
type DamageUpdateList = readonly {
@@ -396,6 +408,8 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,
396408
experimental,
397409
getCellRenderer,
398410
resizeIndicator = "full",
411+
columnSelectionGridLines = true,
412+
rowSelectionGridLines = true,
399413
} = p;
400414
const translateX = p.translateX ?? 0;
401415
const translateY = p.translateY ?? 0;
@@ -829,6 +843,8 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,
829843
getCellRenderer,
830844
minimumCellWidth,
831845
resizeIndicator,
846+
columnSelectionGridLines,
847+
rowSelectionGridLines,
832848
};
833849

834850
// This confusing bit of code due to some poor design. Long story short, the damage property is only used
@@ -895,6 +911,8 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,
895911
getCellRenderer,
896912
minimumCellWidth,
897913
resizeIndicator,
914+
columnSelectionGridLines,
915+
rowSelectionGridLines,
898916
]);
899917

900918
const lastDrawRef = React.useRef(draw);

packages/core/src/internal/data-grid/render/data-grid-render.lines.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,9 @@ export function drawGridLines(
294294
freezeTrailingRows: number,
295295
rows: number,
296296
theme: FullTheme,
297-
verticalOnly: boolean = false
297+
verticalOnly: boolean = false,
298+
selectedColumns?: CompactSelection,
299+
selectedRows?: CompactSelection
298300
) {
299301
if (spans !== undefined) {
300302
ctx.beginPath();
@@ -307,6 +309,8 @@ export function drawGridLines(
307309
}
308310
const hColor = theme.horizontalBorderColor ?? theme.borderColor;
309311
const vColor = theme.borderColor;
312+
const selectedVColor = theme.accentColor;
313+
const selectedHColor = theme.accentColor;
310314

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

@@ -322,12 +326,20 @@ export function drawGridLines(
322326
x += c.width;
323327
const tx = c.sticky ? x : x + translateX;
324328
if (tx >= minX && tx <= maxX && verticalBorder(index + 1)) {
329+
const leftSelected = selectedColumns?.hasIndex(c.sourceIndex) ?? false;
330+
const rightSelected =
331+
index < effectiveCols.length - 1
332+
? selectedColumns?.hasIndex(effectiveCols[index + 1].sourceIndex) ?? false
333+
: false;
334+
const color = leftSelected !== rightSelected
335+
? selectedVColor
336+
: vColor;
325337
toDraw.push({
326338
x1: tx,
327339
y1: Math.max(groupHeaderHeight, minY),
328340
x2: tx,
329341
y2: Math.min(height, maxY),
330-
color: vColor,
342+
color,
331343
});
332344
}
333345
}
@@ -348,12 +360,25 @@ export function drawGridLines(
348360
const ty = y + translateY;
349361
if (ty >= minY && ty <= maxY - 1) {
350362
const rowTheme = getRowThemeOverride?.(row);
363+
364+
let color = rowTheme?.horizontalBorderColor ?? rowTheme?.borderColor ?? hColor;
365+
366+
if (selectedRows !== undefined) {
367+
const currentSelected = selectedRows.hasIndex(row);
368+
const prevSelected = row > 0 ? selectedRows.hasIndex(row - 1) : false;
369+
370+
// Accent the line if it is a boundary between selected and unselected rows.
371+
if (currentSelected !== prevSelected && (currentSelected || prevSelected)) {
372+
color = selectedHColor;
373+
}
374+
}
375+
351376
toDraw.push({
352377
x1: minX,
353378
y1: ty,
354379
x2: maxX,
355380
y2: ty,
356-
color: rowTheme?.horizontalBorderColor ?? rowTheme?.borderColor ?? hColor,
381+
color,
357382
});
358383
}
359384

packages/core/src/internal/data-grid/render/data-grid-render.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,17 @@ export function drawGrid(arg: DrawGridArg, lastArg: DrawGridArg | undefined) {
268268
}
269269
}
270270
const drawHeaderTexture = () => {
271+
272+
// Draw the bottom border of the header.
273+
overlayCtx.beginPath();
274+
overlayCtx.moveTo(0, overlayHeight - 0.5);
275+
overlayCtx.lineTo(width, overlayHeight - 0.5);
276+
overlayCtx.strokeStyle = blend(
277+
theme.headerBottomBorderColor ?? theme.horizontalBorderColor ?? theme.borderColor,
278+
theme.bgHeader
279+
);
280+
overlayCtx.stroke();
281+
271282
drawGridHeaders(
272283
overlayCtx,
273284
effectiveCols,
@@ -308,17 +319,10 @@ export function drawGrid(arg: DrawGridArg, lastArg: DrawGridArg | undefined) {
308319
freezeTrailingRows,
309320
rows,
310321
theme,
311-
true
312-
);
313-
314-
overlayCtx.beginPath();
315-
overlayCtx.moveTo(0, overlayHeight - 0.5);
316-
overlayCtx.lineTo(width, overlayHeight - 0.5);
317-
overlayCtx.strokeStyle = blend(
318-
theme.headerBottomBorderColor ?? theme.horizontalBorderColor ?? theme.borderColor,
319-
theme.bgHeader
322+
true,
323+
arg.columnSelectionGridLines ? selection.columns : undefined,
324+
arg.rowSelectionGridLines ? selection.rows : undefined
320325
);
321-
overlayCtx.stroke();
322326

323327
if (mustDrawHighlightRingsOnHeader) {
324328
drawHighlightRings(
@@ -716,7 +720,10 @@ export function drawGrid(arg: DrawGridArg, lastArg: DrawGridArg | undefined) {
716720
verticalBorder,
717721
freezeTrailingRows,
718722
rows,
719-
theme
723+
theme,
724+
false,
725+
arg.columnSelectionGridLines ? selection.columns : undefined,
726+
arg.rowSelectionGridLines ? selection.rows : undefined
720727
);
721728

722729
highlightRedraw?.();

packages/core/src/internal/data-grid/render/draw-grid-arg.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,6 @@ export interface DrawGridArg {
7979
readonly getCellRenderer: GetCellRendererCallback;
8080
readonly minimumCellWidth: number;
8181
readonly resizeIndicator: "full" | "header" | "none";
82+
readonly columnSelectionGridLines: boolean;
83+
readonly rowSelectionGridLines: boolean;
8284
}

0 commit comments

Comments
 (0)