Skip to content

Commit 349a672

Browse files
Expand cell height if there is only one row
2 parents 85cb30d + e68c8c6 commit 349a672

File tree

8 files changed

+157
-25
lines changed

8 files changed

+157
-25
lines changed

src/components/Grid/Cell.tsx

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
1-
import { memo } from "react";
1+
import { memo, useEffect, useRef } from "react";
22
import { GridChildComponentProps, areEqual } from "react-window";
33
import { ItemDataType } from "./types";
44
import { StyledCell } from "./StyledCell";
55

66
type CellProps = GridChildComponentProps<ItemDataType> & {
77
width: number;
8-
}
8+
};
99

1010
export const Cell = memo(
11-
({
12-
data,
13-
rowIndex,
14-
columnIndex,
15-
style,
16-
...props
17-
}: CellProps) => {
11+
({ data, rowIndex, columnIndex, style, ...props }: CellProps) => {
1812
const {
1913
cell: CellData,
2014
getSelectionType,
@@ -25,6 +19,8 @@ export const Cell = memo(
2519
showHeader,
2620
rowHeight,
2721
rowStart,
22+
rowAutoHeight,
23+
updateRowHeight,
2824
} = data;
2925

3026
const currentRowIndex = rowIndex + rowStart;
@@ -60,11 +56,29 @@ export const Cell = memo(
6056
const selectionBorderLeft = rightOfSelectionBorder || rightOfFocus || isFocused;
6157
const selectionBorderTop = belowSelectionBorder || belowFocus || isFocused;
6258

59+
const cellRef = useRef<HTMLDivElement>(null);
60+
61+
useEffect(() => {
62+
if (!rowAutoHeight) {
63+
return;
64+
}
65+
if (cellRef.current) {
66+
const height = cellRef.current.getBoundingClientRect().height;
67+
updateRowHeight(rowIndex, height);
68+
}
69+
}, [updateRowHeight, rowIndex, rowAutoHeight]);
70+
71+
const styleWithHeight = {
72+
...style,
73+
height: "auto",
74+
};
75+
6376
return (
6477
<div
65-
style={style}
78+
style={styleWithHeight}
6679
data-row={currentRowIndex}
6780
data-column={columnIndex}
81+
ref={cellRef}
6882
>
6983
<StyledCell
7084
as={CellData}
@@ -85,6 +99,7 @@ export const Cell = memo(
8599
data-grid-row={currentRowIndex}
86100
data-grid-column={columnIndex}
87101
$showBorder
102+
$rowAutoHeight={rowAutoHeight}
88103
{...props}
89104
/>
90105
</div>

src/components/Grid/Grid.stories.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@ import { useCallback, useEffect, useState } from "react";
22
import { CellProps, GridContextMenuItemProps, SelectedRegion, SelectionFocus } from "..";
33
import { Grid as CUIGrid } from "./Grid";
44

5-
const Cell: CellProps = ({ type, rowIndex, columnIndex, isScrolling, width, ...props }) => {
5+
const Cell: CellProps = ({
6+
type,
7+
rowIndex,
8+
columnIndex,
9+
isScrolling,
10+
width,
11+
...props
12+
}) => {
613
return (
714
<div
815
data-scrolling={isScrolling}
@@ -20,6 +27,7 @@ interface Props {
2027
row: number;
2128
column: number;
2229
};
30+
rowAutoHeight?: boolean;
2331
}
2432
const Grid = ({ columnCount, rowCount, focus: focusProp, ...props }: Props) => {
2533
const [focus, setFocus] = useState(focusProp);
@@ -71,6 +79,7 @@ const Grid = ({ columnCount, rowCount, focus: focusProp, ...props }: Props) => {
7179
});
7280
}}
7381
getMenuOptions={getMenuOptions}
82+
rowAutoHeight={props.rowAutoHeight}
7483
{...props}
7584
/>
7685
</div>

src/components/Grid/Grid.test.tsx

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,32 @@
1-
import {CellProps, Grid, GridProps} from "@/components";
2-
import {renderCUI} from "@/utils/test-utils";
3-
import {SelectionFocus} from "./types";
4-
import {ReactNode} from "react";
1+
import { CellProps, Grid, GridProps } from "@/components";
2+
import { renderCUI } from "@/utils/test-utils";
3+
import { SelectionFocus } from "./types";
4+
import { ReactNode } from "react";
55

66
const Cell: CellProps = ({ type, rowIndex, columnIndex, isScrolling, ...props }) => {
7+
let content = `${rowIndex} ${columnIndex} - ${type}`;
8+
9+
if (rowIndex === 0 && columnIndex === 0) {
10+
content = `CREATE TABLE random_user_events (
11+
user_id UInt32,
12+
event_time DateTime,
13+
event_type Enum8('click' = 1, 'view' = 2, 'purchase' = 3),
14+
item_id String,
15+
price Decimal(10,2),
16+
quantity UInt16
17+
) ENGINE = MergeTree()
18+
ORDER BY (user_id, event_time)
19+
PARTITION BY toYYYYMM(event_time)
20+
SETTINGS index_granularity = 8192;`;
21+
}
22+
723
return (
824
<div
925
data-scrolling={isScrolling}
1026
{...props}
1127
data-testid={`${type}-${rowIndex ?? "x"}-${columnIndex ?? "x"}`}
1228
>
13-
{rowIndex} {columnIndex} - {type}
29+
{content}
1430
</div>
1531
);
1632
};
@@ -31,6 +47,7 @@ interface Props
3147
focus?: SelectionFocus;
3248
onFocusChange?: (rowIndex: number, columnIndex: number) => void;
3349
onColumnResize?: () => void;
50+
rowAutoHeight?: boolean;
3451
}
3552
type AutoSizerModule = typeof import("react-virtualized-auto-sizer");
3653

@@ -60,6 +77,7 @@ describe("Grid", () => {
6077
onColumnResize,
6178
focus,
6279
onFocusChange,
80+
rowAutoHeight,
6381
...props
6482
}: Props) =>
6583
renderCUI(
@@ -72,6 +90,7 @@ describe("Grid", () => {
7290
onColumnResize={onColumnResize ?? onColumnResizeTestFn}
7391
onFocusChange={onFocusChange ?? onFocusChangeTestFn}
7492
getMenuOptions={getMenuOptions}
93+
rowAutoHeight={rowAutoHeight}
7594
{...props}
7695
/>
7796
);
@@ -99,4 +118,31 @@ describe("Grid", () => {
99118
cell && expect(cell.dataset.selected).toEqual("true");
100119
cell && expect(cell.dataset.focused).toEqual("true");
101120
});
121+
122+
it("should set row height to default (33px) when rowAutoHeight is false", async () => {
123+
const { getByTestId } = renderGrid({
124+
rowCount: 10,
125+
columnCount: 10,
126+
rowAutoHeight: false,
127+
});
128+
129+
const cell = getByTestId("row-cell-0-0");
130+
131+
const computedHeight = window.getComputedStyle(cell).height;
132+
const heightValue = parseFloat(computedHeight);
133+
expect(heightValue).toBe(33);
134+
});
135+
136+
it("should expand row height to 100% when rowAutoHeight is true", async () => {
137+
const { getByTestId } = renderGrid({
138+
rowCount: 1,
139+
columnCount: 1,
140+
rowAutoHeight: true,
141+
});
142+
143+
const cell = getByTestId("row-cell-0-0");
144+
145+
const computedHeight = window.getComputedStyle(cell).height;
146+
expect(computedHeight).toBe("100%");
147+
});
102148
});

src/components/Grid/Grid.tsx

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ export const Grid = forwardRef<HTMLDivElement, GridProps>(
149149
onContextMenu: onContextMenuProp,
150150
forwardedGridRef,
151151
onItemsRendered: onItemsRenderedProp,
152+
rowAutoHeight,
152153
...props
153154
},
154155
forwardedRef
@@ -212,6 +213,34 @@ export const Grid = forwardRef<HTMLDivElement, GridProps>(
212213
onCopyCallback,
213214
]);
214215

216+
const rowHeightsRef = useRef(new Map());
217+
218+
const getRowHeight = useCallback(
219+
(index: number) => {
220+
if (rowAutoHeight && rowHeightsRef.current.get(index)) {
221+
return rowHeightsRef.current.get(index) + rowHeight;
222+
}
223+
return rowHeight;
224+
},
225+
[rowHeight, rowAutoHeight]
226+
);
227+
228+
const updateRowHeight = useCallback(
229+
(rowIndex: number, height: number) => {
230+
if (!rowAutoHeight) {
231+
return;
232+
}
233+
const prevHeight = rowHeightsRef.current.get(rowIndex) ?? 0;
234+
if (height > prevHeight) {
235+
rowHeightsRef.current.set(rowIndex, height);
236+
if (gridRef.current) {
237+
gridRef.current.resetAfterRowIndex(rowIndex);
238+
}
239+
}
240+
},
241+
[rowAutoHeight]
242+
);
243+
215244
const customOnCopy: () => Promise<void> = useMemo(() => {
216245
const result = async () => {
217246
if (onCopyProp) {
@@ -405,6 +434,9 @@ export const Grid = forwardRef<HTMLDivElement, GridProps>(
405434
headerHeight,
406435
rowNumberWidth,
407436
rowStart,
437+
rowAutoHeight,
438+
updateRowHeight,
439+
getRowHeight,
408440
};
409441

410442
const InnerElementType = forwardRef<HTMLDivElement, InnerElementTypeTypes>(
@@ -435,6 +467,7 @@ export const Grid = forwardRef<HTMLDivElement, GridProps>(
435467
showHeader={showHeader}
436468
rowStart={rowStart}
437469
showBorder={showBorder}
470+
rowAutoHeight={rowAutoHeight}
438471
/>
439472
)}
440473

@@ -755,7 +788,6 @@ export const Grid = forwardRef<HTMLDivElement, GridProps>(
755788
const onItemsRendered = useCallback(
756789
(props: GridOnItemsRenderedProps) => {
757790
lastItemsRenderedProps.current = props;
758-
759791
return onItemsRenderedProp?.({
760792
...props,
761793
visibleRowStartIndex: props.visibleRowStartIndex + rowStart,
@@ -786,6 +818,13 @@ export const Grid = forwardRef<HTMLDivElement, GridProps>(
786818
);
787819
};
788820

821+
// Handles the case when rowCount/columnCount changes, rerenders styles
822+
useEffect(() => {
823+
if (gridRef.current) {
824+
gridRef.current.resetAfterRowIndex(0);
825+
}
826+
}, [rowCount, columnCount]);
827+
789828
return (
790829
<ContextMenu
791830
modal={false}
@@ -820,7 +859,7 @@ export const Grid = forwardRef<HTMLDivElement, GridProps>(
820859
height={height}
821860
width={width}
822861
columnCount={columnCount}
823-
rowHeight={() => rowHeight}
862+
rowHeight={getRowHeight}
824863
useIsScrolling={useIsScrolling}
825864
innerElementType={InnerElementType}
826865
itemData={data}

src/components/Grid/Header.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ const RowColumnContainer = styled(HeaderCellContainer)<{
9999
const RowColumn = styled(StyledCell)`
100100
width: 100%;
101101
text-align: right;
102+
overflow: hidden;
102103
`;
103104

104105
const Column = ({
@@ -130,7 +131,7 @@ const Column = ({
130131
(leftSelectionType === "selectDirect" || isSelected) &&
131132
leftSelectionType !== selectionType;
132133

133-
const columnWidth = getColumnWidth(columnIndex)
134+
const columnWidth = getColumnWidth(columnIndex);
134135
return (
135136
<HeaderCellContainer
136137
$width={columnWidth}
@@ -186,7 +187,7 @@ const Header = ({
186187
getColumnHorizontalPosition,
187188
getResizerPosition,
188189
showBorder,
189-
resizingState
190+
resizingState,
190191
}: HeaderProps) => {
191192
const selectedAllType = getSelectionType({
192193
type: "all",

0 commit comments

Comments
 (0)