Skip to content

Commit

Permalink
fix: table height sync
Browse files Browse the repository at this point in the history
  • Loading branch information
helloqian12138 committed Jan 22, 2025
1 parent 2b5e1af commit 60a984b
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 69 deletions.
2 changes: 1 addition & 1 deletion packages/drip-table-generator/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "drip-table-generator",
"version": "3.2.2-alpha.8",
"version": "3.2.2-alpha.9",
"description": "A visualization tool for generating schema of drip-table.",
"main": "dist/index.min.js",
"module": "lib/index.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { DripTableGeneratorProps } from '@/typing';

import EditableTable from '../..';
import ColumnHeader from '../column-header';
import { RightFixedColumnsHandler } from '../right-columns';
import { ScrollableColumnsHandler } from '../scroll-columns';
import TableSection from '../table-section';

export interface LeftFixedColumnsProps<
Expand All @@ -28,14 +30,14 @@ export interface LeftFixedColumnsProps<
tableConfig: DTGTableConfig;
previewDataSource: ({ id: number; record: RecordType })[];
containerWidth: number;
rowHeight: number | undefined;
siblings: [React.RefObject<ScrollableColumnsHandler>, React.RefObject<RightFixedColumnsHandler>];
columnList: { id: number; column: DTGTableConfig['columns'][number] }[];
ref?: React.RefObject<LeftFixedColumnsHandler>;
rowHeaderHeights?: number[];
}

export interface LeftFixedColumnsHandler {
getRowHeight: () => number[];
getRowHeight: () => number;
getSubTableHeight: () => number[];
}

Expand All @@ -48,8 +50,10 @@ function LeftFixedColumnsInner<
) {
const { tableConfigs } = React.useContext(TableConfigsContext);
const currentTableIndex = tableConfigs.findIndex(c => c.tableId === props.tableConfig.tableId);
const [rowHeight, setRowHeight] = React.useState(void 0 as number | undefined);
const rowRef = React.createRef<HTMLDivElement>();
const containerRef = React.createRef<HTMLDivElement>();

const leftMargins = React.useMemo(() => {
let margin = 0;
if (props.tableConfig.hasSubTable) {
Expand All @@ -68,20 +72,34 @@ function LeftFixedColumnsInner<
}
return margin;
}, [props.tableConfig.hasSubTable, props.tableConfig.configs, props.columnList]);
React.useImperativeHandle(ref, () => ({
getRowHeight: () => {
let maxCellHeight = 0;
const rowHeight = rowRef.current?.offsetHeight ?? 0;
for (const element of (rowRef.current?.children || []) as HTMLDivElement[]) {
if (element.children[0]) {
const trueCellHeight = (element.children[0] as HTMLDivElement).offsetHeight + 28;
if (trueCellHeight > maxCellHeight) {
maxCellHeight = trueCellHeight;
}

const getCurrentRowHeight = () => {
let maxCellHeight = 0;
const currentRowHeight = rowRef.current?.offsetHeight ?? 0;
for (const element of (rowRef.current?.children || []) as HTMLDivElement[]) {
if (element.children[0]) {
const trueCellHeight = (element.children[0] as HTMLDivElement).offsetHeight + 28;
if (trueCellHeight > maxCellHeight) {
maxCellHeight = trueCellHeight;
}
}
return [rowHeight, maxCellHeight];
},
}
return currentRowHeight - maxCellHeight === 1 ? currentRowHeight : maxCellHeight;
};

React.useEffect(() => {
const currentRowHeight = getCurrentRowHeight();
const [scrollRef, rightRef] = props.siblings;
const scrollColumnsHeight = scrollRef.current?.getRowHeight() || 0;
const rightFixedColumnsHeight = rightRef.current?.getRowHeight() || 0;
const maxSiblingsHeight = Math.max(scrollColumnsHeight, rightFixedColumnsHeight);
if (maxSiblingsHeight > currentRowHeight) {
setRowHeight(maxSiblingsHeight);
}
}, [props.columnList, props.tableConfig, props.dataSource]);

React.useImperativeHandle(ref, () => ({
getRowHeight: getCurrentRowHeight,
getSubTableHeight: () => {
const rows = (containerRef.current?.children || []) as HTMLDivElement[];
const start = props.tableConfig.configs.showHeader ? 1 : 0;
Expand Down Expand Up @@ -174,7 +192,7 @@ function LeftFixedColumnsInner<
stripe: props.tableConfig.configs.stripe && rowIndex % 2 === 1,
})}
ref={rowRef}
style={{ height: props.rowHeight }}
style={{ height: rowHeight }}
>
{props.tableConfig.hasSubTable && (
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { DTGTableConfig } from '@/context/table-configs';
import { DripTableGeneratorProps } from '@/typing';

import ColumnHeader from '../column-header';
import { LeftFixedColumnsHandler } from '../left-columns';
import { ScrollableColumnsHandler } from '../scroll-columns';
import TableSection from '../table-section';

export interface RightFixedColumnsProps<
Expand All @@ -24,15 +26,15 @@ export interface RightFixedColumnsProps<
tableConfig: DTGTableConfig;
previewDataSource: ({ id: number; record: RecordType })[];
containerWidth: number;
rowHeight: number | undefined;
siblings: [React.RefObject<LeftFixedColumnsHandler>, React.RefObject<ScrollableColumnsHandler>];
columnList: { id: number; column: DTGTableConfig['columns'][number] }[];
ref?: React.RefObject<RightFixedColumnsHandler>;
subTableHeights?: number[];
rowHeaderHeights?: number[];
}

export interface RightFixedColumnsHandler {
getRowHeight: () => number[];
getRowHeight: () => number;
}

function RightFixedColumnsInner<
Expand All @@ -43,20 +45,35 @@ function RightFixedColumnsInner<
ref: React.ForwardedRef<RightFixedColumnsHandler>,
) {
const rowRef = React.createRef<HTMLDivElement>();
React.useImperativeHandle(ref, () => ({
getRowHeight: () => {
let maxCellHeight = 0;
const rowHeight = rowRef.current?.offsetHeight ?? 0;
for (const element of (rowRef.current?.children || []) as HTMLDivElement[]) {
if (element.children[0]) {
const trueCellHeight = (element.children[0] as HTMLDivElement).offsetHeight + 28;
if (trueCellHeight > maxCellHeight) {
maxCellHeight = trueCellHeight;
}
const [rowHeight, setRowHeight] = React.useState(void 0 as number | undefined);

const getCurrentRowHeight = () => {
let maxCellHeight = 0;
const currentRowHeight = rowRef.current?.offsetHeight ?? 0;
for (const element of (rowRef.current?.children || []) as HTMLDivElement[]) {
if (element.children[0]) {
const trueCellHeight = (element.children[0] as HTMLDivElement).offsetHeight + 28;
if (trueCellHeight > maxCellHeight) {
maxCellHeight = trueCellHeight;
}
}
return [rowHeight, maxCellHeight];
},
}
return currentRowHeight - maxCellHeight === 1 ? currentRowHeight : maxCellHeight;
};

React.useEffect(() => {
const currentRowHeight = getCurrentRowHeight();
const [leftRef, scrollRef] = props.siblings;
const leftFixedColumnsHeight = leftRef.current?.getRowHeight() || 0;
const scrollColumnsHeight = scrollRef.current?.getRowHeight() || 0;
const maxSiblingsHeight = Math.max(scrollColumnsHeight, leftFixedColumnsHeight);
if (maxSiblingsHeight > currentRowHeight) {
setRowHeight(maxSiblingsHeight);
}
}, [props.columnList, props.tableConfig, props.dataSource]);

React.useImperativeHandle(ref, () => ({
getRowHeight: getCurrentRowHeight,
}));
return (
<div
Expand Down Expand Up @@ -97,7 +114,7 @@ function RightFixedColumnsInner<
stripe: props.tableConfig.configs.stripe && rowIndex % 2 === 1,
})}
ref={rowRef}
style={{ height: props.rowHeight }}
style={{ height: rowHeight }}
>
<TableSection
{...props}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { DTGTableConfig } from '@/context/table-configs';
import { DripTableGeneratorProps } from '@/typing';

import ColumnHeader from '../column-header';
import { LeftFixedColumnsHandler } from '../left-columns';
import { RightFixedColumnsHandler } from '../right-columns';
import RowHeader from '../row/row-header';
import TableSection from '../table-section';

Expand All @@ -25,14 +27,14 @@ export interface ScrollableColumnsProps<
tableConfig: DTGTableConfig;
previewDataSource: ({ id: number; record: RecordType })[];
containerWidth: number;
rowHeight: number | undefined;
siblings: [React.RefObject<LeftFixedColumnsHandler>, React.RefObject<RightFixedColumnsHandler>];
columnList: { id: number; column: DTGTableConfig['columns'][number] }[];
ref?: React.RefObject<ScrollableColumnsHandler>;
subTableHeights?: number[];
}

export interface ScrollableColumnsHandler {
getRowHeight: () => number[];
getRowHeight: () => number;
getRowHeaderHeights: () => number[];
}

Expand All @@ -45,20 +47,35 @@ function ScrollableColumnsInner<
) {
const rowRef = React.createRef<HTMLDivElement>();
const containerRef = React.createRef<HTMLDivElement>();
React.useImperativeHandle(ref, () => ({
getRowHeight: () => {
let maxCellHeight = 0;
const rowHeight = rowRef.current?.offsetHeight ?? 0;
for (const element of (rowRef.current?.children || []) as HTMLDivElement[]) {
if (element.children[0]) {
const trueCellHeight = (element.children[0] as HTMLDivElement).offsetHeight + 28;
if (trueCellHeight > maxCellHeight) {
maxCellHeight = trueCellHeight;
}
const [rowHeight, setRowHeight] = React.useState(void 0 as number | undefined);

const getCurrentRowHeight = () => {
let maxCellHeight = 0;
const currentRowHeight = rowRef.current?.offsetHeight ?? 0;
for (const element of (rowRef.current?.children || []) as HTMLDivElement[]) {
if (element.children[0]) {
const trueCellHeight = (element.children[0] as HTMLDivElement).offsetHeight + 28;
if (trueCellHeight > maxCellHeight) {
maxCellHeight = trueCellHeight;
}
}
return [rowHeight, maxCellHeight];
},
}
return currentRowHeight - maxCellHeight === 1 ? currentRowHeight : maxCellHeight;
};

React.useEffect(() => {
const currentRowHeight = getCurrentRowHeight();
const [leftRef, rightRef] = props.siblings;
const leftFixedColumnsHeight = leftRef.current?.getRowHeight() || 0;
const rightFixedColumnsHeight = rightRef.current?.getRowHeight() || 0;
const maxSiblingsHeight = Math.max(rightFixedColumnsHeight, leftFixedColumnsHeight);
if (maxSiblingsHeight > currentRowHeight) {
setRowHeight(maxSiblingsHeight);
}
}, [props.columnList, props.tableConfig, props.dataSource]);

React.useImperativeHandle(ref, () => ({
getRowHeight: getCurrentRowHeight,
getRowHeaderHeights: () => {
const rows = (containerRef.current?.children || []) as HTMLDivElement[];
const start = props.tableConfig.configs.showHeader ? 1 : 0;
Expand Down Expand Up @@ -117,7 +134,7 @@ function ScrollableColumnsInner<
stripe: props.tableConfig.configs.stripe && rowIndex % 2 === 1,
})}
ref={rowRef}
style={{ height: props.rowHeight }}
style={{ height: rowHeight }}
>
<TableSection
{...props}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,12 @@ function EditableTable<
>(props: EditableTableProps<RecordType, ExtraOptions>) {
const context = React.useContext(TableConfigsContext);
const [previewRecord] = React.useState(void 0 as number | undefined);
const [rowHeight, setRowHeight] = React.useState(void 0 as number | undefined);
const [subTableHeights, setSubTableHeights] = React.useState([] as number[]);
const [rowHeaderHeights, setRowHeaderHeights] = React.useState([] as number[]);
const containerRef = React.useRef<TableContainerHandler>(null);
const leftColumnsRef = React.useRef<LeftFixedColumnsHandler>(null);
const scrollColumnsRef = React.useRef<ScrollableColumnsHandler>(null);
const rightColumnsRef = React.useRef<RightFixedColumnsHandler>(null);
const lastRowHeights = React.useRef<number[]>([]);

const tableHeight = React.useMemo(() => {
if (props.tableConfig.configs.scroll?.y && typeof props.tableConfig.configs.scroll?.y !== 'boolean') {
Expand Down Expand Up @@ -93,24 +91,6 @@ function EditableTable<
rightFixedColumns = filterArray(columnList, item => item.column.fixed === 'right' || (item.column.fixed && item.id > sortableColumns[0].id));
}

React.useEffect(() => {
const [leftRowHeight, leftCellHeight] = leftColumnsRef.current?.getRowHeight() ?? [0, 0];
const [scrollRowHeight, scrollCellHeight] = scrollColumnsRef.current?.getRowHeight() ?? [0, 0];
const [rightRowHeight, rightCellHeight] = rightColumnsRef.current?.getRowHeight() ?? [0, 0];
if (lastRowHeights.current.length <= 0) {
if (leftRowHeight !== scrollRowHeight || rightRowHeight !== scrollCellHeight || leftRowHeight !== rightRowHeight) {
setRowHeight(Math.max(leftCellHeight, scrollCellHeight, rightCellHeight) + 1);
lastRowHeights.current = [leftCellHeight, scrollCellHeight, rightCellHeight];
}
} else {
const [lastLeftHeight, lastScrollHeight, lastRightHeight] = lastRowHeights.current ?? [];
if (lastLeftHeight !== leftCellHeight || Math.abs(lastScrollHeight - scrollCellHeight) > 1 || lastRightHeight !== rightCellHeight) {
setRowHeight(Math.max(leftCellHeight, scrollCellHeight, rightCellHeight) + 1);
lastRowHeights.current = [leftCellHeight, scrollCellHeight, rightCellHeight];
}
}
}, [props.dataSource, props.schema, props.tableConfig]);

React.useEffect(() => {
setTimeout(() => {
const leftHeights = leftColumnsRef.current?.getSubTableHeight() ?? [];
Expand Down Expand Up @@ -160,8 +140,8 @@ function EditableTable<
columnList={leftFixedColumns}
previewDataSource={previewDataSource as ({ id: number; record: RecordType })[]}
containerWidth={tableWidth}
rowHeight={rowHeight}
rowHeaderHeights={rowHeaderHeights}
siblings={[scrollColumnsRef, rightColumnsRef]}
/>
<ScrollableColumns<RecordType, ExtraOptions>
{...props}
Expand All @@ -170,8 +150,8 @@ function EditableTable<
columnList={sortableColumns}
previewDataSource={previewDataSource}
containerWidth={tableWidth}
rowHeight={rowHeight}
subTableHeights={subTableHeights}
siblings={[leftColumnsRef, rightColumnsRef]}
/>
<RightFixedColumns<RecordType, ExtraOptions>
{...props}
Expand All @@ -180,9 +160,9 @@ function EditableTable<
columnList={rightFixedColumns}
previewDataSource={previewDataSource}
containerWidth={tableWidth}
rowHeight={rowHeight}
subTableHeights={subTableHeights}
rowHeaderHeights={rowHeaderHeights}
siblings={[leftColumnsRef, scrollColumnsRef]}
/>
</div>
<AddColumnComponent
Expand Down

0 comments on commit 60a984b

Please sign in to comment.