@gmfe/table-x 2.14.30-beta.2 → 2.14.30-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -80,13 +80,16 @@ export function rebuildNestedColumnsFromFlat(flatColumns) {
|
|
|
80
80
|
}
|
|
81
81
|
})
|
|
82
82
|
|
|
83
|
-
// 特殊列(select、diy、expand
|
|
83
|
+
// 特殊列(select、diy、expand)的处理
|
|
84
84
|
// 从 flatColumns 中提取特殊列,保持它们在 flatColumns 中的相对顺序
|
|
85
85
|
const specialCols = flatColumns.filter(col =>
|
|
86
86
|
specialColumnIds.includes(col.id)
|
|
87
87
|
)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
88
|
+
|
|
89
|
+
// 分离 fixed: 'left' 的特殊列和其他特殊列
|
|
90
|
+
const leftFixedSpecialCols = specialCols.filter(col => col.fixed === 'left')
|
|
91
|
+
const otherSpecialCols = specialCols.filter(col => col.fixed !== 'left')
|
|
92
|
+
|
|
93
|
+
// 按顺序:fixed: 'left' 的特殊列 -> 普通列 -> 其他特殊列
|
|
94
|
+
return [...leftFixedSpecialCols, ...nested, ...otherSpecialCols]
|
|
92
95
|
}
|
|
@@ -6,12 +6,64 @@ import React from 'react'
|
|
|
6
6
|
// cell.render('Cell') 是一个react组件,如果这个组件return undefined,那就就会报错
|
|
7
7
|
// 这里是为了兼容 cell.render('Cell') 返回undefined的情况
|
|
8
8
|
class TdCatchErr extends React.Component {
|
|
9
|
+
state = {
|
|
10
|
+
hasError: false
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
static getDerivedStateFromError(error) {
|
|
14
|
+
// 捕获子组件树中的错误,返回新的 state
|
|
15
|
+
return { hasError: true }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
componentDidCatch(error, errorInfo) {
|
|
19
|
+
// 静默处理错误,不打印日志
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
render() {
|
|
23
|
+
if (this.state.hasError) {
|
|
24
|
+
return null
|
|
25
|
+
}
|
|
26
|
+
const children = this.props.children
|
|
27
|
+
// 如果 children 是 undefined 或 null,返回 null(React 允许返回 null)
|
|
28
|
+
if (children === undefined || children === null) {
|
|
29
|
+
return null
|
|
30
|
+
}
|
|
31
|
+
return children
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 创建一个包装组件,用于包装 Cell 组件的 type,确保它总是返回有效值
|
|
36
|
+
// 这个组件会包装原始的 Cell 组件,如果原始组件返回 undefined,就返回 null
|
|
37
|
+
const SafeCellWrapper = OriginalComponent => {
|
|
38
|
+
return function WrappedCell(props) {
|
|
39
|
+
try {
|
|
40
|
+
const result = OriginalComponent(props)
|
|
41
|
+
// 如果原始组件返回 undefined,返回 null
|
|
42
|
+
return result === undefined ? null : result
|
|
43
|
+
} catch (error) {
|
|
44
|
+
return null
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 错误边界组件,专门用于捕获 Cell 组件返回 undefined 的错误
|
|
50
|
+
class SafeCellErrorBoundary extends React.Component {
|
|
51
|
+
state = {
|
|
52
|
+
hasError: false
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static getDerivedStateFromError(error) {
|
|
56
|
+
return { hasError: true }
|
|
57
|
+
}
|
|
58
|
+
|
|
9
59
|
componentDidCatch(error, errorInfo) {
|
|
10
|
-
|
|
11
|
-
console.warn(errorInfo.componentStack)
|
|
60
|
+
// 静默处理错误
|
|
12
61
|
}
|
|
13
62
|
|
|
14
63
|
render() {
|
|
64
|
+
if (this.state.hasError) {
|
|
65
|
+
return null
|
|
66
|
+
}
|
|
15
67
|
return this.props.children
|
|
16
68
|
}
|
|
17
69
|
}
|
|
@@ -40,12 +92,26 @@ const Td = ({ cell, totalWidth }) => {
|
|
|
40
92
|
}
|
|
41
93
|
|
|
42
94
|
// 如果 Cell 返回 undefined,转换为 null(null 不会报错,undefined 会)
|
|
43
|
-
|
|
44
|
-
|
|
95
|
+
let cellContent = cell.render('Cell')
|
|
96
|
+
|
|
97
|
+
// cellContent 是一个 React 元素,但它的 type(组件)在渲染时可能返回 undefined
|
|
98
|
+
// 我们需要用一个包装组件来替换原始的 type,确保总是返回有效值
|
|
99
|
+
if (cellContent && React.isValidElement(cellContent)) {
|
|
100
|
+
// 创建一个新的 React 元素,用包装组件替换原始的 type
|
|
101
|
+
const OriginalComponent = cellContent.type
|
|
102
|
+
const WrappedComponent = SafeCellWrapper(OriginalComponent)
|
|
103
|
+
cellContent = React.createElement(
|
|
104
|
+
SafeCellErrorBoundary,
|
|
105
|
+
null,
|
|
106
|
+
React.createElement(WrappedComponent, cellContent.props)
|
|
107
|
+
)
|
|
108
|
+
} else if (cellContent === undefined || cellContent === null) {
|
|
109
|
+
cellContent = null
|
|
110
|
+
}
|
|
45
111
|
|
|
46
112
|
return (
|
|
47
113
|
<td {...tdProps}>
|
|
48
|
-
<TdCatchErr>{
|
|
114
|
+
<TdCatchErr>{cellContent}</TdCatchErr>
|
|
49
115
|
</td>
|
|
50
116
|
)
|
|
51
117
|
}
|
|
@@ -174,7 +174,12 @@ const TwoLevelTHead = ({ headerGroups, firstLevelHeaders, totalWidth }) => {
|
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
|
-
const {
|
|
177
|
+
const {
|
|
178
|
+
colSpan: hpColSpan,
|
|
179
|
+
rowSpan: hpRowSpan,
|
|
180
|
+
key: hpKey,
|
|
181
|
+
...restHp
|
|
182
|
+
} = hp || {}
|
|
178
183
|
const finalRowSpan =
|
|
179
184
|
rowSpan !== undefined ? Number(rowSpan) : undefined
|
|
180
185
|
const finalColSpan =
|
|
@@ -201,8 +206,12 @@ const TwoLevelTHead = ({ headerGroups, firstLevelHeaders, totalWidth }) => {
|
|
|
201
206
|
style: cellStyle
|
|
202
207
|
}
|
|
203
208
|
|
|
209
|
+
// 生成唯一的 key:结合 id/accessor 和索引,确保即使 id/accessor 相同,key 也是唯一的
|
|
210
|
+
// 如果有 hpKey,也加上索引以确保唯一性(因为 hpKey 可能也会重复)
|
|
211
|
+
const baseKey = hpKey || header.id || header.accessor
|
|
212
|
+
const headerKey = baseKey ? `${baseKey}-${idx}` : `header-${idx}`
|
|
204
213
|
return (
|
|
205
|
-
<th key={
|
|
214
|
+
<th key={headerKey} {...thProps}>
|
|
206
215
|
{typeof header.Header === 'function' ? (
|
|
207
216
|
<header.Header />
|
|
208
217
|
) : (
|
|
@@ -248,9 +257,15 @@ const TwoLevelTHead = ({ headerGroups, firstLevelHeaders, totalWidth }) => {
|
|
|
248
257
|
) {
|
|
249
258
|
return null
|
|
250
259
|
}
|
|
260
|
+
// 生成唯一的 key:结合 id/accessor 和索引,确保即使 id/accessor 相同,key 也是唯一的
|
|
261
|
+
const columnKey = column.id
|
|
262
|
+
? `${column.id}-${idx}`
|
|
263
|
+
: column.accessor
|
|
264
|
+
? `${column.accessor}-${idx}`
|
|
265
|
+
: `col-${idx}`
|
|
251
266
|
return (
|
|
252
267
|
<Th
|
|
253
|
-
key={
|
|
268
|
+
key={columnKey}
|
|
254
269
|
column={{
|
|
255
270
|
...column,
|
|
256
271
|
// column.fixed 已经在 transformColumnsForTwoLevel 中正确设置
|
|
@@ -51,11 +51,16 @@ export function transformColumnsForTwoLevel(columns) {
|
|
|
51
51
|
|
|
52
52
|
// 分离普通列和特殊列
|
|
53
53
|
const normalColumns = []
|
|
54
|
-
const
|
|
54
|
+
const leftFixedSpecialColumns = [] // fixed: 'left' 的特殊列(如 diy)
|
|
55
|
+
const otherSpecialColumns = [] // 其他特殊列(如 select、expand)
|
|
55
56
|
|
|
56
57
|
columns.forEach(column => {
|
|
57
58
|
if (specialColumnIds.includes(column.id)) {
|
|
58
|
-
|
|
59
|
+
if (column.fixed === 'left') {
|
|
60
|
+
leftFixedSpecialColumns.push(column)
|
|
61
|
+
} else {
|
|
62
|
+
otherSpecialColumns.push(column)
|
|
63
|
+
}
|
|
59
64
|
} else {
|
|
60
65
|
normalColumns.push(column)
|
|
61
66
|
}
|
|
@@ -125,10 +130,21 @@ export function transformColumnsForTwoLevel(columns) {
|
|
|
125
130
|
}
|
|
126
131
|
})
|
|
127
132
|
|
|
128
|
-
//
|
|
133
|
+
// 处理 fixed: 'left' 的特殊列(如 diy),放在最前面
|
|
134
|
+
leftFixedSpecialColumns.forEach(column => {
|
|
135
|
+
transformedColumns.unshift(column)
|
|
136
|
+
firstLevelHeaders.unshift({
|
|
137
|
+
...column,
|
|
138
|
+
hasSubColumns: false,
|
|
139
|
+
subColumnCount: 1,
|
|
140
|
+
isSpecialColumn: true
|
|
141
|
+
})
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
// 最后处理其他特殊列(select、expand)放在最后
|
|
129
145
|
// 注意:移除特殊列的 fixed 属性,让它们按数组顺序显示在最后(不固定)
|
|
130
146
|
// 如果用户需要特殊列固定在右边,可以手动设置 fixed: 'right'
|
|
131
|
-
|
|
147
|
+
otherSpecialColumns.forEach(column => {
|
|
132
148
|
const { fixed, ...columnWithoutFixed } = column
|
|
133
149
|
const adjustedColumn = {
|
|
134
150
|
...columnWithoutFixed,
|