mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2024-12-09 04:31:35 +08:00
feat(data-table): column.rowSpan & colSpan
This commit is contained in:
parent
b59309fee8
commit
f56d978344
@ -2,6 +2,10 @@
|
||||
|
||||
## Pending
|
||||
|
||||
### Feats
|
||||
|
||||
- `n-data-table`'s column add `colSpan` and `rowSpan` prop.
|
||||
|
||||
### Fixes
|
||||
|
||||
- Fix `n-dropdown` with `x` and `y` set logs errors when mouse move outside it.
|
||||
@ -20,7 +24,7 @@
|
||||
- `n-popover` default `delay` is set to `100`.
|
||||
- `n-tooltip` default `showArrow` is set to `true`.
|
||||
|
||||
### Feat
|
||||
### Feats
|
||||
|
||||
- `n-config-provider` prop `theme-overrides` support inheritance.
|
||||
- `n-card` add `hoverable` prop.
|
||||
@ -39,7 +43,7 @@
|
||||
|
||||
## 2.0.1
|
||||
|
||||
### Feat
|
||||
### Feats
|
||||
|
||||
- `n-layout-sider` add `default-collapsed` prop.
|
||||
- `n-modal` support custom position.
|
||||
|
@ -2,6 +2,10 @@
|
||||
|
||||
## Pending
|
||||
|
||||
### Feats
|
||||
|
||||
- `n-data-table` column 新增 `colSpan` 和 `rowSpan` 属性
|
||||
|
||||
### Fixes
|
||||
|
||||
- 修正 `n-dropdown` 在设定 `x` 和 `y` 之后鼠标在外面移动会报错
|
||||
@ -20,7 +24,7 @@
|
||||
- `n-popover` 默认 `delay` 设为 `100`
|
||||
- `n-tooltip` 默认 `showArrow` 设为 `true`
|
||||
|
||||
### Feat
|
||||
### Feats
|
||||
|
||||
- `n-config-provider` 的 `theme-overrides` 支持继承
|
||||
- `n-card` 新增 `hoverable` 属性
|
||||
@ -39,7 +43,7 @@
|
||||
|
||||
## 2.0.1
|
||||
|
||||
### Feat
|
||||
### Feats
|
||||
|
||||
- `n-layout-sider` 新增 `default-collapsed` 属性
|
||||
- `n-modal` 支持自定义位置
|
||||
|
@ -5,9 +5,10 @@
|
||||
```
|
||||
|
||||
```js
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import { h, defineComponent } from 'vue'
|
||||
import { NTag, NButton, useMessage } from 'naive-ui'
|
||||
|
||||
const createColumns = (instance) => {
|
||||
const createColumns = ({ sendMail }) => {
|
||||
return [
|
||||
{
|
||||
title: 'Name',
|
||||
@ -31,14 +32,16 @@ const createColumns = (instance) => {
|
||||
render (row) {
|
||||
const tags = row.tags.map((tagKey) => {
|
||||
return h(
|
||||
resolveComponent('n-tag'),
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px'
|
||||
},
|
||||
type: 'info'
|
||||
},
|
||||
{ default: () => tagKey }
|
||||
{
|
||||
default: () => tagKey
|
||||
}
|
||||
)
|
||||
})
|
||||
return tags
|
||||
@ -50,10 +53,10 @@ const createColumns = (instance) => {
|
||||
width: '20%',
|
||||
render (row) {
|
||||
return h(
|
||||
resolveComponent('n-button'),
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
onClick: () => instance.sendMail(row)
|
||||
onClick: () => sendMail(row)
|
||||
},
|
||||
{ default: () => 'Send Email' }
|
||||
)
|
||||
@ -62,7 +65,7 @@ const createColumns = (instance) => {
|
||||
]
|
||||
}
|
||||
|
||||
const data = [
|
||||
const createData = () => [
|
||||
{
|
||||
key: 0,
|
||||
name: 'John Brown',
|
||||
@ -86,23 +89,20 @@ const data = [
|
||||
}
|
||||
]
|
||||
|
||||
export default {
|
||||
inject: ['message'],
|
||||
data () {
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
const message = useMessage()
|
||||
return {
|
||||
data: data,
|
||||
columns: createColumns(this)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pagination () {
|
||||
return { total: this.data.length, pageSize: 10 }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
sendMail (rowData) {
|
||||
this.message.info('send mail to ' + rowData.name)
|
||||
data: createData(),
|
||||
columns: createColumns({
|
||||
sendMail (rowData) {
|
||||
message.info('send mail to ' + rowData.name)
|
||||
}
|
||||
}),
|
||||
pagination: {
|
||||
pageSize: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
@ -110,7 +110,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
pagination () {
|
||||
return { total: this.data.length, pageSize: 10 }
|
||||
return { pageSize: 10 }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -15,6 +15,7 @@ basic
|
||||
empty
|
||||
border
|
||||
size
|
||||
merge-cell
|
||||
filter-and-sorter
|
||||
select
|
||||
group-header
|
||||
@ -79,6 +80,7 @@ These methods can help you control table in an uncontrolled manner. However, it'
|
||||
| align | `'left' \| 'right' \| 'center'` | `'left'` | Text align in column |
|
||||
| children | `Column[]` | `undefined` | Child nodes of a grouped column |
|
||||
| className | `string` | `undefined` | |
|
||||
| colSpan | `(rowData: Object, rowIndex: number) => number` | `undefined` | |
|
||||
| defaultFilterOptionValue | `string \| number \| null` | `null` | The default active filter option value in uncontrolled manner. (works when not using multiple filters) |
|
||||
| defaultFilterOptionValues | `Array<string \| number>` | `[]` | The default active filter option values in uncontrolled manner. (works when there are multiple filters) |
|
||||
| defaultSortOrder | `'descend' \| 'ascend' \| false` | `false` | The default sort order of the table in uncontrolled manner |
|
||||
@ -94,6 +96,7 @@ These methods can help you control table in an uncontrolled manner. However, it'
|
||||
| key | `string \| number` | **required** | Unique key of this column, **required** when table's row-key is not set. |
|
||||
| render | `(rowData: Object) => VNodeChild` | `undefined` | Render function of column row cell. |
|
||||
| renderFilterMenu | `() => VNodeChild` | `undefined` | Render function of column filter menu. |
|
||||
| rowSpan | `(rowData: Object, rowIndex: number) => number` | `undefined` | |
|
||||
| sortOrder | `'descend' \| 'ascend' \| false` | `undefined` | The controlled sort order of the column. If multiple columns' sortOrder is set, the first one will affect. |
|
||||
| sorter | `boolean \| function \| 'default'` | `false` | The sorter of the column. If set `'default'`, it will use a basic builtin compare function. If set to `true`, it will only display sort icon on the column, which can be used in async status. Otherwise it works like `Array.sort`'s compare function. |
|
||||
| title | `string \| (() => VNodeChild)` | `undefined` | Can be a render function |
|
||||
|
118
src/data-table/demos/enUS/merge-cell.demo.md
Normal file
118
src/data-table/demos/enUS/merge-cell.demo.md
Normal file
@ -0,0 +1,118 @@
|
||||
# Merge Cell
|
||||
|
||||
Set colspan and rowspan by setting `colSpan` and `rowSpan` of column object.
|
||||
|
||||
```html
|
||||
<n-data-table
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
:pagination="pagination"
|
||||
:single-line="false"
|
||||
/>
|
||||
```
|
||||
|
||||
```js
|
||||
import { h, defineComponent } from 'vue'
|
||||
import { NTag, NButton, useMessage } from 'naive-ui'
|
||||
|
||||
const createColumns = ({ sendMail }) => {
|
||||
return [
|
||||
{
|
||||
title: 'Name',
|
||||
key: 'name',
|
||||
width: '15%',
|
||||
rowSpan: (rowData, rowIndex) => (rowIndex === 0 ? 2 : 1),
|
||||
colSpan: (rowData, rowIndex) => (rowIndex === 0 ? 2 : 1)
|
||||
},
|
||||
{
|
||||
title: 'Age',
|
||||
key: 'age',
|
||||
width: '10%'
|
||||
},
|
||||
{
|
||||
title: 'Address',
|
||||
key: 'address',
|
||||
width: '20%',
|
||||
colSpan: (rowData, rowIndex) => (rowIndex === 2 ? 2 : 1)
|
||||
},
|
||||
{
|
||||
title: 'Tags',
|
||||
key: 'tags',
|
||||
width: '20%',
|
||||
render (row) {
|
||||
const tags = row.tags.map((tagKey) => {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px'
|
||||
},
|
||||
type: 'info'
|
||||
},
|
||||
{
|
||||
default: () => tagKey
|
||||
}
|
||||
)
|
||||
})
|
||||
return tags
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Action',
|
||||
key: 'actions',
|
||||
width: '20%',
|
||||
render (row) {
|
||||
return h(
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
onClick: () => sendMail(row)
|
||||
},
|
||||
{ default: () => 'Send Email' }
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const createData = () => [
|
||||
{
|
||||
key: 0,
|
||||
name: 'John Brown',
|
||||
age: 32,
|
||||
address: 'New York No. 1 Lake Park',
|
||||
tags: ['nice', 'developer']
|
||||
},
|
||||
{
|
||||
key: 1,
|
||||
name: 'Jim Green',
|
||||
age: 42,
|
||||
address: 'London No. 1 Lake Park',
|
||||
tags: ['loser']
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
name: 'Joe Black',
|
||||
age: 32,
|
||||
address: 'Sidney No. 1 Lake Park',
|
||||
tags: ['cool', 'teacher']
|
||||
}
|
||||
]
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
const message = useMessage()
|
||||
return {
|
||||
data: createData(),
|
||||
columns: createColumns({
|
||||
sendMail (rowData) {
|
||||
message.info('send mail to ' + rowData.name)
|
||||
}
|
||||
}),
|
||||
pagination: {
|
||||
pageSize: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
@ -109,7 +109,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
pagination () {
|
||||
return { total: this.data.length, pageSize: 10 }
|
||||
return { pageSize: 10 }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -5,9 +5,10 @@
|
||||
```
|
||||
|
||||
```js
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import { h, defineComponent } from 'vue'
|
||||
import { NTag, NButton, useMessage } from 'naive-ui'
|
||||
|
||||
const createColumns = (instance) => {
|
||||
const createColumns = ({ sendMail }) => {
|
||||
return [
|
||||
{
|
||||
title: 'Name',
|
||||
@ -31,7 +32,7 @@ const createColumns = (instance) => {
|
||||
render (row) {
|
||||
const tags = row.tags.map((tagKey) => {
|
||||
return h(
|
||||
resolveComponent('n-tag'),
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px'
|
||||
@ -52,10 +53,10 @@ const createColumns = (instance) => {
|
||||
width: '20%',
|
||||
render (row) {
|
||||
return h(
|
||||
resolveComponent('n-button'),
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
onClick: () => instance.sendMail(row)
|
||||
onClick: () => sendMail(row)
|
||||
},
|
||||
{ default: () => 'Send Email' }
|
||||
)
|
||||
@ -64,7 +65,7 @@ const createColumns = (instance) => {
|
||||
]
|
||||
}
|
||||
|
||||
const data = [
|
||||
const createData = () => [
|
||||
{
|
||||
key: 0,
|
||||
name: 'John Brown',
|
||||
@ -88,23 +89,20 @@ const data = [
|
||||
}
|
||||
]
|
||||
|
||||
export default {
|
||||
inject: ['message'],
|
||||
data () {
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
const message = useMessage()
|
||||
return {
|
||||
data: data,
|
||||
columns: createColumns(this)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pagination () {
|
||||
return { total: this.data.length, pageSize: 10 }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
sendMail (rowData) {
|
||||
this.message.info('send mail to ' + rowData.name)
|
||||
data: createData(),
|
||||
columns: createColumns({
|
||||
sendMail (rowData) {
|
||||
message.info('send mail to ' + rowData.name)
|
||||
}
|
||||
}),
|
||||
pagination: {
|
||||
pageSize: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
@ -110,7 +110,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
pagination () {
|
||||
return { total: this.data.length, pageSize: 10 }
|
||||
return { pageSize: 10 }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -15,6 +15,7 @@ basic
|
||||
empty
|
||||
border
|
||||
size
|
||||
merge-cell
|
||||
filter-and-sorter
|
||||
select
|
||||
group-header
|
||||
@ -79,6 +80,7 @@ custom-filter-menu
|
||||
| align | `'left' \| 'right' \| 'center'` | `'left'` | 列内的文本排列 |
|
||||
| children | `Column[]` | `undefined` | 成组列头的子节点 |
|
||||
| className | `string` | `undefined` | |
|
||||
| colSpan | `(rowData: Object, rowIndex: number) => number` | `undefined` | |
|
||||
| defaultFilterOptionValue | `string \| number \| null` | `null` | 非受控状态下默认的过滤器选项值(过滤器单选时生效) |
|
||||
| defaultFilterOptionValues | `Array<string \| number>` | `[]` | 非受控状态下默认的过滤器选项值(过滤器多选时生效) |
|
||||
| defaultSortOrder | `'descend' \| 'ascend' \| false` | `false` | 非受控状态下表格默认的排序方式 |
|
||||
@ -94,6 +96,7 @@ custom-filter-menu
|
||||
| key | `string \| number` | **必须** | 这一列的 key,在表格未设定 row-key 的时候是**必须**的。 |
|
||||
| render | `(rowData: Object) => VNodeChild` | `undefined` | 渲染函数,渲染这一列的每一行的单元格 |
|
||||
| renderFilterMenu | `() => VNodeChild` | `undefined` | 渲染函数,渲染这一列的过滤器菜单 |
|
||||
| rowSpan | `(rowData: Object, rowIndex: number) => number` | `undefined` | |
|
||||
| sortOrder | `'descend' \| 'ascend' \| false` | `undefined` | 受控状态下表格的排序方式。如果多列都设定了有效值,那么只有第一个会生效 |
|
||||
| sorter | `boolean \| function \| 'default'` | `undefined` | 这一列的排序方法。如果设为 `'default'` 表格将会使用一个内置的排序函数;如果设为 `true`,表格将只会在这列展示一个排序图标,在异步的时候可能有用。其他情况下它工作的方式类似 `Array.sort` 的对比函数 |
|
||||
| title | `string \| (() => VNodeChild)` | `undefined` | 可以是渲染函数 |
|
||||
|
118
src/data-table/demos/zhCN/merge-cell.demo.md
Normal file
118
src/data-table/demos/zhCN/merge-cell.demo.md
Normal file
@ -0,0 +1,118 @@
|
||||
# 合并单元格
|
||||
|
||||
设定列的 `colSpan` 和 `rowSpan` 来控制单元格的 `colspan` 和 `rowspan`。
|
||||
|
||||
```html
|
||||
<n-data-table
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
:pagination="pagination"
|
||||
:single-line="false"
|
||||
/>
|
||||
```
|
||||
|
||||
```js
|
||||
import { h, defineComponent } from 'vue'
|
||||
import { NTag, NButton, useMessage } from 'naive-ui'
|
||||
|
||||
const createColumns = ({ sendMail }) => {
|
||||
return [
|
||||
{
|
||||
title: 'Name',
|
||||
key: 'name',
|
||||
width: '15%',
|
||||
rowSpan: (rowData, rowIndex) => (rowIndex === 0 ? 2 : 1),
|
||||
colSpan: (rowData, rowIndex) => (rowIndex === 0 ? 2 : 1)
|
||||
},
|
||||
{
|
||||
title: 'Age',
|
||||
key: 'age',
|
||||
width: '10%'
|
||||
},
|
||||
{
|
||||
title: 'Address',
|
||||
key: 'address',
|
||||
width: '20%',
|
||||
colSpan: (rowData, rowIndex) => (rowIndex === 2 ? 2 : 1)
|
||||
},
|
||||
{
|
||||
title: 'Tags',
|
||||
key: 'tags',
|
||||
width: '20%',
|
||||
render (row) {
|
||||
const tags = row.tags.map((tagKey) => {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px'
|
||||
},
|
||||
type: 'info'
|
||||
},
|
||||
{
|
||||
default: () => tagKey
|
||||
}
|
||||
)
|
||||
})
|
||||
return tags
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Action',
|
||||
key: 'actions',
|
||||
width: '20%',
|
||||
render (row) {
|
||||
return h(
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
onClick: () => sendMail(row)
|
||||
},
|
||||
{ default: () => 'Send Email' }
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const createData = () => [
|
||||
{
|
||||
key: 0,
|
||||
name: 'John Brown',
|
||||
age: 32,
|
||||
address: 'New York No. 1 Lake Park',
|
||||
tags: ['nice', 'developer']
|
||||
},
|
||||
{
|
||||
key: 1,
|
||||
name: 'Jim Green',
|
||||
age: 42,
|
||||
address: 'London No. 1 Lake Park',
|
||||
tags: ['loser']
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
name: 'Joe Black',
|
||||
age: 32,
|
||||
address: 'Sidney No. 1 Lake Park',
|
||||
tags: ['cool', 'teacher']
|
||||
}
|
||||
]
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
const message = useMessage()
|
||||
return {
|
||||
data: createData(),
|
||||
columns: createColumns({
|
||||
sendMail (rowData) {
|
||||
message.info('send mail to ' + rowData.name)
|
||||
}
|
||||
}),
|
||||
pagination: {
|
||||
pageSize: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
@ -109,7 +109,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
pagination () {
|
||||
return { total: this.data.length, pageSize: 10 }
|
||||
return { pageSize: 10 }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -64,95 +64,138 @@ export default defineComponent({
|
||||
onScroll={handleScroll}
|
||||
>
|
||||
{{
|
||||
default: () => (
|
||||
<table ref="body" class="n-data-table-table">
|
||||
<colgroup>
|
||||
{NDataTable.cols.map((col) => (
|
||||
<col key={col.key} style={col.style}></col>
|
||||
))}
|
||||
</colgroup>
|
||||
<tbody ref="tbody" class="n-data-table-tbody">
|
||||
{NDataTable.paginatedData.map((tmNode, index) => {
|
||||
const { rawNode: row } = tmNode
|
||||
const { handleCheckboxUpdateChecked } = this
|
||||
const {
|
||||
mergedTheme,
|
||||
cols,
|
||||
fixedColumnLeftMap,
|
||||
fixedColumnRightMap,
|
||||
currentPage,
|
||||
mergedCheckedRowKeys,
|
||||
rowClassName,
|
||||
leftActiveFixedColKey,
|
||||
rightActiveFixedColKey
|
||||
} = NDataTable
|
||||
return (
|
||||
<tr
|
||||
key={tmNode.key}
|
||||
class={[
|
||||
'n-data-table-tr',
|
||||
createRowClassName(row, index, rowClassName)
|
||||
]}
|
||||
>
|
||||
{cols.map((col) => {
|
||||
const { key, column } = col
|
||||
return (
|
||||
<td
|
||||
key={key}
|
||||
style={{
|
||||
textAlign: column.align || undefined,
|
||||
left: pxfy(fixedColumnLeftMap[key]),
|
||||
right: pxfy(fixedColumnRightMap[key])
|
||||
}}
|
||||
class={[
|
||||
'n-data-table-td',
|
||||
column.className,
|
||||
column.fixed &&
|
||||
`n-data-table-td--fixed-${column.fixed}`,
|
||||
column.align &&
|
||||
`n-data-table-td--${column.align}-align`,
|
||||
{
|
||||
'n-data-table-td--ellipsis':
|
||||
column.ellipsis === true ||
|
||||
// don't add ellpisis class if tooltip exists
|
||||
(column.ellipsis && !column.ellipsis.tooltip),
|
||||
'n-data-table-td--shadow-after':
|
||||
leftActiveFixedColKey === key,
|
||||
'n-data-table-td--shadow-before':
|
||||
rightActiveFixedColKey === key,
|
||||
'n-data-table-td--selection':
|
||||
column.type === 'selection'
|
||||
}
|
||||
]}
|
||||
>
|
||||
{column.type === 'selection' ? (
|
||||
<NCheckbox
|
||||
key={currentPage}
|
||||
disabled={column.disabled?.(row)}
|
||||
checked={mergedCheckedRowKeys.includes(
|
||||
tmNode.key
|
||||
)}
|
||||
onUpdateChecked={(checked) =>
|
||||
handleCheckboxUpdateChecked(tmNode, checked)
|
||||
default: () => {
|
||||
const cordToPass: Record<number, number[]> = {}
|
||||
return (
|
||||
<table ref="body" class="n-data-table-table">
|
||||
<colgroup>
|
||||
{NDataTable.cols.map((col) => (
|
||||
<col key={col.key} style={col.style}></col>
|
||||
))}
|
||||
</colgroup>
|
||||
<tbody ref="tbody" class="n-data-table-tbody">
|
||||
{NDataTable.paginatedData.map((tmNode, rowIndex) => {
|
||||
const { rawNode: row } = tmNode
|
||||
const { handleCheckboxUpdateChecked } = this
|
||||
const {
|
||||
mergedTheme,
|
||||
cols,
|
||||
fixedColumnLeftMap,
|
||||
fixedColumnRightMap,
|
||||
currentPage,
|
||||
mergedCheckedRowKeys,
|
||||
rowClassName,
|
||||
leftActiveFixedColKey,
|
||||
rightActiveFixedColKey
|
||||
} = NDataTable
|
||||
return (
|
||||
<tr
|
||||
key={tmNode.key}
|
||||
class={[
|
||||
'n-data-table-tr',
|
||||
createRowClassName(row, rowIndex, rowClassName)
|
||||
]}
|
||||
>
|
||||
{cols.map((col, colIndex) => {
|
||||
if (rowIndex in cordToPass) {
|
||||
const cordOfRowToPass = cordToPass[rowIndex]
|
||||
const indexInCordOfRowToPass = cordOfRowToPass.indexOf(
|
||||
colIndex
|
||||
)
|
||||
if (~indexInCordOfRowToPass) {
|
||||
cordOfRowToPass.splice(indexInCordOfRowToPass, 1)
|
||||
return null
|
||||
}
|
||||
}
|
||||
const { key, column } = col
|
||||
const { rowSpan, colSpan } = column
|
||||
const mergedColSpan = colSpan
|
||||
? colSpan(row, rowIndex)
|
||||
: 1
|
||||
const mergedRowSpan = rowSpan
|
||||
? rowSpan(row, rowIndex)
|
||||
: 1
|
||||
if (mergedColSpan > 1 || mergedRowSpan > 1) {
|
||||
for (
|
||||
let i = rowIndex;
|
||||
i < rowIndex + mergedRowSpan;
|
||||
++i
|
||||
) {
|
||||
for (
|
||||
let j = colIndex;
|
||||
j < colIndex + mergedColSpan;
|
||||
++j
|
||||
) {
|
||||
if (i === rowIndex && j === colIndex) continue
|
||||
if (!(i in cordToPass)) {
|
||||
cordToPass[i] = [j]
|
||||
} else {
|
||||
cordToPass[i].push(j)
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<Cell
|
||||
index={index}
|
||||
row={row}
|
||||
column={column}
|
||||
mergedTheme={mergedTheme}
|
||||
/>
|
||||
)}
|
||||
</td>
|
||||
)
|
||||
})}
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
<td
|
||||
key={key}
|
||||
style={{
|
||||
textAlign: column.align || undefined,
|
||||
left: pxfy(fixedColumnLeftMap[key]),
|
||||
right: pxfy(fixedColumnRightMap[key])
|
||||
}}
|
||||
colspan={mergedColSpan}
|
||||
rowspan={mergedRowSpan}
|
||||
class={[
|
||||
'n-data-table-td',
|
||||
column.className,
|
||||
column.fixed &&
|
||||
`n-data-table-td--fixed-${column.fixed}`,
|
||||
column.align &&
|
||||
`n-data-table-td--${column.align}-align`,
|
||||
{
|
||||
'n-data-table-td--ellipsis':
|
||||
column.ellipsis === true ||
|
||||
// don't add ellpisis class if tooltip exists
|
||||
(column.ellipsis &&
|
||||
!column.ellipsis.tooltip),
|
||||
'n-data-table-td--shadow-after':
|
||||
leftActiveFixedColKey === key,
|
||||
'n-data-table-td--shadow-before':
|
||||
rightActiveFixedColKey === key,
|
||||
'n-data-table-td--selection':
|
||||
column.type === 'selection'
|
||||
}
|
||||
]}
|
||||
>
|
||||
{column.type === 'selection' ? (
|
||||
<NCheckbox
|
||||
key={currentPage}
|
||||
disabled={column.disabled?.(row)}
|
||||
checked={mergedCheckedRowKeys.includes(
|
||||
tmNode.key
|
||||
)}
|
||||
onUpdateChecked={(checked) =>
|
||||
handleCheckboxUpdateChecked(tmNode, checked)
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<Cell
|
||||
index={rowIndex}
|
||||
row={row}
|
||||
column={column}
|
||||
mergedTheme={mergedTheme}
|
||||
/>
|
||||
)}
|
||||
</td>
|
||||
)
|
||||
})}
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
}
|
||||
}}
|
||||
</NScrollbar>
|
||||
)
|
||||
|
@ -84,6 +84,8 @@ export type TableColumnInfo = {
|
||||
renderFilterMenu?: FilterMenuRender
|
||||
renderSorter?: SorterRender
|
||||
renderFilter?: FilterRender
|
||||
colSpan?: (data: TableNode, index: number) => number
|
||||
rowSpan?: (data: TableNode, index: number) => number
|
||||
} & CommonColInfo
|
||||
|
||||
export type SelectionColInfo = {
|
||||
@ -96,6 +98,8 @@ export type SelectionColInfo = {
|
||||
filterOptions?: never
|
||||
filterOptionValues?: never
|
||||
filterOptionValue?: never
|
||||
colSpan?: never
|
||||
rowSpan?: never
|
||||
} & CommonColInfo
|
||||
|
||||
export type TableColumn = TableColumnGroup | TableColumnInfo | SelectionColInfo
|
||||
|
Loading…
Reference in New Issue
Block a user