Skip to content

Commit

Permalink
add row count gutter (#218)
Browse files Browse the repository at this point in the history
  • Loading branch information
invisal authored Dec 22, 2024
1 parent c3644b8 commit 7f21faf
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 16 deletions.
18 changes: 17 additions & 1 deletion src/components/gui/table-optimized/OptimizeTableState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,14 @@ export default class OptimizeTableState {
protected focus: [number, number] | null = null;
protected selectedRows = new Set<number>();
protected data: OptimizeTableRowValue[] = [];

// Gutter is a sticky column on the left side of the table
// We primary use it to display row number at the moment
public gutterColumnWidth = 40;

protected headers: OptimizeTableHeaderProps[] = [];
protected headerWidth: number[] = [];

protected editMode = false;
protected readOnlyMode = false;
public mismatchDetection = false;
Expand All @@ -42,7 +48,7 @@ export default class OptimizeTableState {
dataResult: DatabaseResultSet,
schemaResult?: DatabaseTableSchema
) {
return new OptimizeTableState(
const r = new OptimizeTableState(
dataResult.headers.map((header) => {
const headerData = schemaResult
? schemaResult.columns.find((c) => c.name === header.name)
Expand Down Expand Up @@ -115,6 +121,16 @@ export default class OptimizeTableState {
}),
dataResult.rows.map((r) => ({ ...r }))
);

if (r.getRowsCount() >= 1000) {
r.gutterColumnWidth = 50;
}

if (r.getRowsCount() >= 10000) {
r.gutterColumnWidth = 60;
}

return r;
}

constructor(
Expand Down
4 changes: 2 additions & 2 deletions src/components/gui/table-optimized/TableFakeBodyPadding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default function TableFakeBodyPadding({
<td
style={{
height: paddingTop,
gridColumn: `span ${colCount}`,
gridColumn: `span ${colCount + 1}`,
}}
/>
</tr>
Expand All @@ -37,7 +37,7 @@ export default function TableFakeBodyPadding({
<td
style={{
height: paddingBottom,
gridColumn: `span ${colCount}`,
gridColumn: `span ${colCount + 1}`,
}}
></td>
</tr>
Expand Down
13 changes: 8 additions & 5 deletions src/components/gui/table-optimized/TableHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { type ReactElement } from "react";
import type { OptimizeTableHeaderWithIndexProps } from ".";
import TableHeaderResizeHandler from "./TableHeaderResizeHandler";
import { cn } from "../../lib/utils";
import OptimizeTableState from "./OptimizeTableState";

export default function TableHeader({
idx,
Expand All @@ -10,32 +11,34 @@ export default function TableHeader({
onContextMenu,
sticky,
renderHeader,
state,
}: {
idx: number;
sticky: boolean;
header: OptimizeTableHeaderWithIndexProps;
state: OptimizeTableState;
onHeaderResize: (idx: number, newWidth: number) => void;
onContextMenu?: React.MouseEventHandler;
renderHeader: (
props: OptimizeTableHeaderWithIndexProps,
idx: number
) => ReactElement;
}) {
const className = cn(
sticky ? "sticky left-0 z-30" : undefined,
"bg-background"
);
const className = cn(sticky ? "sticky z-30" : undefined, "bg-background");

return (
<th
key={header.name}
title={header.tooltip}
className={className}
onContextMenu={onContextMenu}
style={{
left: sticky ? state.gutterColumnWidth : undefined,
}}
>
{renderHeader(header, idx)}
{header.resizable && (
<TableHeaderResizeHandler idx={idx} onResize={onHeaderResize} />
<TableHeaderResizeHandler idx={idx + 1} onResize={onHeaderResize} />
)}
</th>
);
Expand Down
9 changes: 9 additions & 0 deletions src/components/gui/table-optimized/TableHeaderList.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { ReactElement } from "react";
import { OptimizeTableHeaderWithIndexProps } from ".";
import TableHeader from "./TableHeader";
import OptimizeTableState from "./OptimizeTableState";

export default function TableHeaderList({
headers,
onHeaderResize,
renderHeader,
sticky,
onHeaderContextMenu,
state,
}: {
headers: OptimizeTableHeaderWithIndexProps[];
renderHeader: (
Expand All @@ -20,10 +22,16 @@ export default function TableHeaderList({
e: React.MouseEvent,
header: OptimizeTableHeaderWithIndexProps
) => void;
state: OptimizeTableState;
}) {
return (
<thead>
<tr>
<th className="sticky left-0 !bg-zinc-100 !dark:bg-zinc-900 z-30">
<div className="libsql-table-cell flex items-center justify-end h-full pr-2 font-mono font-bold">
#
</div>
</th>
{headers.map((header, idx) => {
return (
<TableHeader
Expand All @@ -33,6 +41,7 @@ export default function TableHeaderList({
renderHeader={renderHeader}
idx={idx}
onHeaderResize={onHeaderResize}
state={state}
onContextMenu={(e) => {
if (onHeaderContextMenu) {
onHeaderContextMenu(e, header);
Expand Down
5 changes: 3 additions & 2 deletions src/components/gui/table-optimized/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export function getVisibleCellRange(
headerSizes: number[],
totalRowCount: number,
rowHeight: number,
renderAhead: number
renderAhead: number,
gutterWidth: number
) {
const currentRowStart = Math.max(
0,
Expand All @@ -27,7 +28,7 @@ export function getVisibleCellRange(
);

let currentColStart = -1;
let currentColAccumulateSize = 0;
let currentColAccumulateSize = gutterWidth;
let currentColEnd = -1;

const visibleXStart = e.scrollLeft;
Expand Down
20 changes: 15 additions & 5 deletions src/components/gui/table-optimized/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,9 @@ function renderCellList({
}: RenderCellListProps) {
const headerSizes = internalState.getHeaderWidth();

const templateSizes = headers
.map((header) => headerSizes[header.index] + "px")
.join(" ");
const templateSizes =
`${internalState.gutterColumnWidth}px ` +
headers.map((header) => headerSizes[header.index] + "px").join(" ");

const onHeaderSizeWithRemap = (idx: number, newWidth: number) => {
onHeaderResize(headerSizes[headers[idx]?.index ?? 0] ?? 150, newWidth);
Expand Down Expand Up @@ -181,10 +181,19 @@ function renderCellList({
data-row={absoluteRowIndex}
className={rowClass}
>
<td
className="sticky left-0 !bg-zinc-100 !dark:bg-zinc-900"
style={{ zIndex: 15 }}
>
<div className="libsql-table-cell flex items-center justify-end h-full pr-2 font-mono">
{absoluteRowIndex + 1}
</div>
</td>

{hasSticky && (
<td
style={{ zIndex: 15 }}
className={cn("sticky left-0", "bg-background")}
style={{ zIndex: 15, left: internalState.gutterColumnWidth + "px" }}
className={cn("sticky", "bg-background")}
onMouseDown={handleCellClicked(
absoluteRowIndex,
headers[0]?.index ?? -1
Expand Down Expand Up @@ -238,6 +247,7 @@ function renderCellList({
return (
<table style={{ ...customStyles, gridTemplateColumns: templateSizes }}>
<TableHeaderList
state={internalState}
renderHeader={renderHeader}
sticky={hasSticky}
headers={headers}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ export default function useTableVisibilityRecalculation({
headers.map((header) => headerSizes[header.index]) as number[],
totalRowCount,
rowHeight,
renderAhead
renderAhead,
state.gutterColumnWidth
)
);
},
Expand Down

0 comments on commit 7f21faf

Please sign in to comment.