-
-
Notifications
You must be signed in to change notification settings - Fork 619
Expand file tree
/
Copy pathuseWidthColumns.tsx
More file actions
104 lines (81 loc) · 2.57 KB
/
useWidthColumns.tsx
File metadata and controls
104 lines (81 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import * as React from 'react';
import type { ColumnsType } from '../../interface';
function parseColWidth(totalWidth: number, width: string | number = '') {
if (typeof width === 'number') {
return width;
}
if (width.endsWith('%')) {
return (totalWidth * parseFloat(width)) / 100;
}
/**
* Column width supports this type of writing, such as '100' and '100px'
*/
if (isNaN(Number(width))) {
if (width.endsWith('px')) {
return Number(width.replace(/px/, ''));
}
} else {
return Number(width);
}
return null;
}
/**
* Fill all column with width
*/
export default function useWidthColumns(
flattenColumns: ColumnsType<any>,
scrollWidth: number,
clientWidth: number,
) {
return React.useMemo<[columns: ColumnsType<any>, realScrollWidth: number]>(() => {
// Fill width if needed
if (scrollWidth && scrollWidth > 0) {
let totalWidth = 0;
let missWidthCount = 0;
// collect not given width column
flattenColumns.forEach((col: any) => {
const colWidth = parseColWidth(scrollWidth, col.width);
if (colWidth) {
totalWidth += colWidth;
} else {
missWidthCount += 1;
}
});
// Fill width
const maxFitWidth = Math.max(scrollWidth, clientWidth);
let restWidth = Math.max(maxFitWidth - totalWidth, missWidthCount);
let restCount = missWidthCount;
const avgWidth = restWidth / missWidthCount;
let realTotal = 0;
const filledColumns = flattenColumns.map((col: any) => {
const clone = {
...col,
};
const colWidth = parseColWidth(scrollWidth, clone.width);
if (colWidth) {
clone.width = colWidth;
} else {
const colAvgWidth = Math.floor(avgWidth);
clone.width = restCount === 1 ? restWidth : colAvgWidth;
restWidth -= colAvgWidth;
restCount -= 1;
}
realTotal += clone.width;
return clone;
});
// If realTotal is less than clientWidth,
// We need extend column width
if (realTotal < maxFitWidth) {
const scale = maxFitWidth / realTotal;
restWidth = maxFitWidth;
filledColumns.forEach((col: any, index) => {
const colWidth = Math.floor(col.width * scale);
col.width = index === filledColumns.length - 1 ? restWidth : colWidth;
restWidth -= colWidth;
});
}
return [filledColumns, Math.max(realTotal, maxFitWidth)];
}
return [flattenColumns, scrollWidth];
}, [flattenColumns, scrollWidth, clientWidth]);
}