Skip to content

Commit

Permalink
progress
Browse files Browse the repository at this point in the history
  • Loading branch information
nstepien committed Aug 10, 2023
1 parent 91f85a6 commit 54dc206
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 69 deletions.
31 changes: 8 additions & 23 deletions src/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
useGridDimensions,
useLatestFunc,
useLayoutEffect,
useMoreCalculatedColumnsStuff,
useViewportColumns,
useViewportRows
} from './hooks';
Expand Down Expand Up @@ -264,8 +265,11 @@ function DataGrid<R, SR, K extends Key>(
/**
* computed values
*/
const { columns, colSpanColumns, lastFrozenColumnIndex, headerRowsCount } = useCalculatedColumns(
rawColumns,
defaultColumnOptions
);
const columnGroupRows = getColumnGroupRows(rawColumns);
const headerRowsCount = 1 + columnGroupRows.length;
const topSummaryRowsCount = topSummaryRows?.length ?? 0;
const bottomSummaryRowsCount = bottomSummaryRows?.length ?? 0;
const summaryRowsCount = topSummaryRowsCount + bottomSummaryRowsCount;
Expand Down Expand Up @@ -330,21 +334,18 @@ function DataGrid<R, SR, K extends Key>(
}, [rows, selectedRows, rowKeyGetter]);

const {
columns,
colSpanColumns,
colOverscanStartIdx,
colOverscanEndIdx,
templateColumns,
layoutCssVars,
lastFrozenColumnIndex,
totalFrozenColumnWidth
} = useCalculatedColumns({
rawColumns,
} = useMoreCalculatedColumnsStuff({
columns,
lastFrozenColumnIndex,
measuredColumnWidths,
resizedColumnWidths,
scrollLeft,
viewportWidth: gridWidth,
defaultColumnOptions,
enableVirtualization
});

Expand Down Expand Up @@ -1214,22 +1215,6 @@ function fdsfdsfs<R, SR>(
}
}

function* iterateOverColumnGroups<R, SR>(
rawColumns: readonly ColumnOrColumnGroup<R, SR>[],
rows: ColumnGroup<R, SR>[][]
) {
for (const rawColumn of rawColumns) {
if ('children' in rawColumn) {
const hasChildren = false;

for (const child of rawColumn.children) {
}

yield <div style={{ gridColumn: -1, gridRow: 1 }}>{rawColumn.name}</div>;
}
}
}

export default forwardRef(DataGrid) as <R, SR = unknown, K extends Key = Key>(
props: DataGridProps<R, SR, K> & RefAttributes<DataGridHandle>
) => JSX.Element;
111 changes: 65 additions & 46 deletions src/hooks/useCalculatedColumns.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import { useMemo } from 'react';

import { clampColumnWidth, max, min } from '../utils';
import type {
CalculatedColumn,
CalculatedColumnOrColumnGroup,
CalculatedColumnParent,
ColumnOrColumnGroup
} from '../types';
import type { CalculatedColumn, CalculatedColumnParent, ColumnOrColumnGroup, Omit } from '../types';
import { renderValue } from '../cellRenderers';
import { SELECT_COLUMN_KEY } from '../Columns';
import type { DataGridProps } from '../DataGrid';

type Mutable<T> = {
-readonly [P in keyof T]: T[P];
-readonly [P in keyof T]: T[P] extends ReadonlyArray<infer V> ? Mutable<V>[] : T[P];
};

interface WithParent<R, SR> {
readonly parent: MutableCalculatedColumnParent<R, SR> | undefined;
}

type MutableCalculatedColumnParent<R, SR> = Omit<Mutable<CalculatedColumnParent<R, SR>>, 'parent'> &
WithParent<R, SR>;
type MutableCalculatedColumn<R, SR> = Omit<Mutable<CalculatedColumn<R, SR>>, 'parent'> &
WithParent<R, SR>;

interface ColumnMetric {
width: number;
left: number;
Expand All @@ -23,73 +27,60 @@ interface ColumnMetric {
const DEFAULT_COLUMN_WIDTH = 'auto';
const DEFAULT_COLUMN_MIN_WIDTH = 50;

interface CalculatedColumnsArgs<R, SR> extends Pick<DataGridProps<R, SR>, 'defaultColumnOptions'> {
rawColumns: readonly ColumnOrColumnGroup<R, SR>[];
viewportWidth: number;
scrollLeft: number;
measuredColumnWidths: ReadonlyMap<string, number>;
resizedColumnWidths: ReadonlyMap<string, number>;
enableVirtualization: boolean;
}

export function useCalculatedColumns<R, SR>({
rawColumns,
measuredColumnWidths,
resizedColumnWidths,
viewportWidth,
scrollLeft,
defaultColumnOptions,
enableVirtualization
}: CalculatedColumnsArgs<R, SR>) {
export function useCalculatedColumns<R, SR>(
rawColumns: readonly ColumnOrColumnGroup<R, SR>[],
defaultColumnOptions: DataGridProps<R, SR>['defaultColumnOptions']
) {
const defaultWidth = defaultColumnOptions?.width ?? DEFAULT_COLUMN_WIDTH;
const defaultMinWidth = defaultColumnOptions?.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;
const defaultMaxWidth = defaultColumnOptions?.maxWidth ?? undefined;
const defaultCellRenderer = defaultColumnOptions?.renderCell ?? renderValue;
const defaultSortable = defaultColumnOptions?.sortable ?? false;
const defaultResizable = defaultColumnOptions?.resizable ?? false;

const { columns, colSpanColumns, lastFrozenColumnIndex } = useMemo((): {
columns: readonly CalculatedColumn<R, SR>[];
colSpanColumns: readonly CalculatedColumn<R, SR>[];
lastFrozenColumnIndex: number;
return useMemo((): {
readonly columns: readonly CalculatedColumn<R, SR>[];
readonly colSpanColumns: readonly CalculatedColumn<R, SR>[];
readonly lastFrozenColumnIndex: number;
readonly headerRowsCount: number;
} => {
let lastFrozenColumnIndex = -1;

const columns: Mutable<CalculatedColumn<R, SR>>[] = [];
const columnGroups: CalculatedColumnParent<R, SR>[] = [];

type MutableCalculatedColumnParent<R, SR> = CalculatedColumnParent<R, SR> & {
readonly children: CalculatedColumnOrColumnGroup<R, SR>[];
};
const columns: MutableCalculatedColumn<R, SR>[] = [];
let headerRowsCount = 1;

iterateRawColumns(rawColumns);
iterateRawColumns(rawColumns, 1);

function iterateRawColumns(
rawColumns: readonly ColumnOrColumnGroup<R, SR>[],
level: number,
parent?: MutableCalculatedColumnParent<R, SR>
) {
if (level > headerRowsCount) headerRowsCount = level;

for (const rawColumn of rawColumns) {
if ('children' in rawColumn) {
const calculatedColumnParent: MutableCalculatedColumnParent<R, SR> = {
parent,
children: []
children: [],
level,
idx: 0
};

if (parent === undefined) {
columnGroups.push(calculatedColumnParent);
} else {
if (parent !== undefined) {
parent.children.push(calculatedColumnParent);
}

iterateRawColumns(rawColumn.children, calculatedColumnParent);
iterateRawColumns(rawColumn.children, level + 1, calculatedColumnParent);
continue;
}

const frozen = rawColumn.frozen ?? false;

const column: CalculatedColumn<R, SR> = {
const column: MutableCalculatedColumn<R, SR> = {
...rawColumn,
parent,
level,
idx: 0,
frozen,
isLastFrozenColumn: false,
Expand Down Expand Up @@ -121,13 +112,16 @@ export function useCalculatedColumns<R, SR>({
}
if (frozenB) return 1;

// TODO: sort columns to keep them grouped if they have a parent

// Sort other columns last:
return 0;
});

const colSpanColumns: CalculatedColumn<R, SR>[] = [];
columns.forEach((column, idx) => {
column.idx = idx;
setColumnGroupIndex(column, idx);

if (column.colSpan != null) {
colSpanColumns.push(column);
Expand All @@ -141,7 +135,8 @@ export function useCalculatedColumns<R, SR>({
return {
columns,
colSpanColumns,
lastFrozenColumnIndex
lastFrozenColumnIndex,
headerRowsCount
};
}, [
rawColumns,
Expand All @@ -152,7 +147,34 @@ export function useCalculatedColumns<R, SR>({
defaultResizable,
defaultSortable
]);
}

function setColumnGroupIndex<R, SR>(column: WithParent<R, SR>, index: number) {
if (column.parent?.children[0] === column) {
column.parent.idx = index;
setColumnGroupIndex(column.parent, index);
}
}

interface CalculatedColumnsArgs<R, SR> {
columns: readonly CalculatedColumn<R, SR>[];
lastFrozenColumnIndex: number;
viewportWidth: number;
scrollLeft: number;
measuredColumnWidths: ReadonlyMap<string, number>;
resizedColumnWidths: ReadonlyMap<string, number>;
enableVirtualization: boolean;
}

export function useMoreCalculatedColumnsStuff<R, SR>({
columns,
lastFrozenColumnIndex,
measuredColumnWidths,
resizedColumnWidths,
viewportWidth,
scrollLeft,
enableVirtualization
}: CalculatedColumnsArgs<R, SR>) {
const { templateColumns, layoutCssVars, totalFrozenColumnWidth, columnMetrics } = useMemo((): {
templateColumns: readonly string[];
layoutCssVars: Readonly<Record<string, string>>;
Expand Down Expand Up @@ -250,13 +272,10 @@ export function useCalculatedColumns<R, SR>({
]);

return {
columns,
colSpanColumns,
colOverscanStartIdx,
colOverscanEndIdx,
templateColumns,
layoutCssVars,
lastFrozenColumnIndex,
totalFrozenColumnWidth
};
}
3 changes: 3 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export interface Column<TRow, TSummaryRow = unknown> {

export interface CalculatedColumn<TRow, TSummaryRow = unknown> extends Column<TRow, TSummaryRow> {
readonly parent: CalculatedColumnParent<TRow, TSummaryRow> | undefined;
readonly level: number;
readonly idx: number;
readonly width: number | string;
readonly minWidth: number;
Expand All @@ -84,6 +85,8 @@ export type CalculatedColumnOrColumnGroup<R, SR> =
export interface CalculatedColumnParent<R, SR> {
readonly parent: CalculatedColumnParent<R, SR> | undefined;
readonly children: readonly CalculatedColumnOrColumnGroup<R, SR>[];
readonly level: number;
readonly idx: number;
}

export type ColumnOrColumnGroup<R, SR> = Column<R, SR> | ColumnGroup<R, SR>;
Expand Down

0 comments on commit 54dc206

Please sign in to comment.