Skip to content

Commit

Permalink
feat(comp: table): add customAdditional to support cosutom row and ce…
Browse files Browse the repository at this point in the history
…ll (#866)

BREAKING CHANGE: `tags`, `rowClassName` and `column.additional` are deprecated, please use `customAdditional` instead
  • Loading branch information
danranVm committed Apr 28, 2022
1 parent 030cadf commit e79b55b
Show file tree
Hide file tree
Showing 29 changed files with 351 additions and 272 deletions.
3 changes: 2 additions & 1 deletion packages/components/config/src/defaultConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,8 @@ export const defaultConfig: GlobalConfig = {
table: {
autoHeight: false,
borderless: true,
rowKey: 'key',
childrenKey: 'children',
getKey: 'key',
size: 'md',
extra: {
icon: 'ellipsis',
Expand Down
10 changes: 8 additions & 2 deletions packages/components/config/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,13 @@ export interface SwitchConfig {
export interface TableConfig {
autoHeight: boolean
borderless: boolean
rowKey: string
childrenKey: string
// eslint-disable-next-line @typescript-eslint/no-explicit-any
getKey: string | ((data: any) => VKey)
/**
* @deprecated please use `getKey` instead'
*/
rowKey?: string
size: TableSize

extra: { icon: string }
Expand All @@ -426,8 +432,8 @@ export interface TableConfig {

export interface TableColumnBaseConfig {
align: TableColumnAlign
sortable: { nextTooltip: boolean; orders: TableColumnSortOrder[] }
filterable: { multiple: boolean; footer: true }
sortable: { nextTooltip: boolean; orders: TableColumnSortOrder[] }
}

export interface TableColumnExpandableConfig {
Expand Down

This file was deleted.

8 changes: 4 additions & 4 deletions packages/components/pagination/src/contents/Sizes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@

import { computed, defineComponent, inject } from 'vue'

import { IxSelect } from '@idux/components/select'
import { IxSelect, type SelectData } from '@idux/components/select'

import { paginationToken } from '../token'

export default defineComponent({
setup() {
const { props, config, locale, mergedPrefixCls, size, activeSize, changePageSize } = inject(paginationToken)!

const sizeOptions = computed(() => {
const sizeData = computed(() => {
const { pageSizes = config.pageSizes } = props
return pageSizes.map(size => {
return {
value: size,
label: size,
}
} as unknown as SelectData
})
})

Expand All @@ -35,7 +35,7 @@ export default defineComponent({
<div class={`${prefixCls}-select-wrapper`}>
<IxSelect
disabled={props.disabled}
dataSource={sizeOptions.value}
dataSource={sizeData.value}
size={size.value}
value={activeSize.value}
onChange={changePageSize}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ exports[`Table > basic work > render work 1`] = `
<!---->
<div class=\\"ix-table-container\\">
<div class=\\"ix-table-content\\">
<table style=\\"table-layout: auto;\\">
<table style=\\"table-layout: auto; height: 100%;\\">
<colgroup>
<col class=\\"ix-table-col-expandable\\">
<col class=\\"ix-table-col-selectable\\">
Expand Down
14 changes: 14 additions & 0 deletions packages/components/table/demo/CustomAdditional.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title:
zh: 斑马纹表格
en: Striped Table
order: 1
---

## zh

使用 `customAdditional` 来自定义表格元素的属性。

## en

Via `customAdditional` to customize the attributes of the table element.
76 changes: 76 additions & 0 deletions packages/components/table/demo/CustomAdditional.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<template>
<IxTable
class="custom-additional-demo-table"
:columns="columns"
:customAdditional="customAdditional"
:dataSource="data"
:pagination="false"
>
<template #name="{ value }">
<a>{{ value }}</a>
</template>
</IxTable>
</template>

<script lang="ts" setup>
import { TableColumn, TableCustomAdditional } from '@idux/components/table'
interface Data {
key: number
name: string
age: number
address: string
}
const customAdditional: TableCustomAdditional<Data> = {
bodyCell: ({ record }) => {
return {
class: 'custom-class',
onClick: () => console.log('cell click', record.key),
}
},
bodyRow: ({ record, rowIndex }) => {
return {
class: (rowIndex + 1) % 2 === 0 ? 'even-row' : 'odd-row',
onClick: () => console.log('row click', record.key),
}
},
}
const columns: TableColumn<Data>[] = [
{
title: 'Name',
dataKey: 'name',
customCell: 'name',
},
{
title: 'Age',
dataKey: 'age',
},
{
title: 'Address',
dataKey: 'address',
},
]
const data: Data[] = []
for (let index = 0; index < 4; index++) {
data.push({
key: index,
name: `Edrward ${index}`,
age: 18 + index,
address: `London Park no. ${index}`,
})
}
</script>

<style scoped lang="less">
.custom-additional-demo-table {
:deep(.even-row) td {
background-color: #fafafa;
}
:deep(.odd-row) td {
background-color: #fff;
}
}
</style>
23 changes: 18 additions & 5 deletions packages/components/table/docs/Index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,19 @@ order: 0
| `v-model:selectedRowKeys` | 选中行的 `key` 数组 | `(string \| number)[]` | - | - | - |
| `autoHeight` | 是否自适应高度 | `boolean` | `false` || - |
| `borderless` | 是否无边框 | `boolean` | `true` || - |
| `childrenKey` | 指定树形结构的 `key` | `string` | `children` | - | - |
| `columns` | 表格列的配置描述, 参见[TableColumn](#TableColumn) | `TableColumn[]` | - | - | - |
| `childrenKey` | 指定树形结构的 `key` | `string` | `children` || - |
| `columns` | 表格列的配置描述 | `TableColumn[]` | - | - | 参见[TableColumn](#TableColumn) |
| `customAdditional` | 自定义表格行和单元格的额外属性 | `TableCustomAdditional[]` | - | - | 参见[TableCustomAdditional](#TableCustomAdditional) |
| `dataSource` | 表格数据数组 | `object[]` | - | - | - |
| `ellipsis` | 超过宽度将自动省略 | `boolean` | `false` | - | - |
| `empty` | 空数据时的内容 | `string \| EmptyProps \| #empty` | - | - | - |
| `getKey` | 获取数据的唯一标识 | `string \| (record: any) => VKey` | `key` || - |
| `headless` | 是否隐藏表头 | `boolean` | `false` | - |- |
| `pagination` | 配置分页器, 参见[TablePagination](#TablePagination) | `boolean \| TablePagination` | - || 设置 `false` 时表示不显示分页 |
| `rowClassName` | 表格行的类名 | `(record: T, rowIndex: number) => string` | - | - | - |
| `rowKey` | 表格行 `key` 的取值 | `string \| record => string \| number` | `key` | - | - |
| `scroll` | 表格滚动配置项,可以指定滚动区域的宽、高, 参见[TableScroll](#TableScroll) | `TableScroll` | - | - | - |
| `size` | 表格大小 | `'lg' \| 'md' \| 'sm'` | `md` ||- |
| `spin` | 表格是否加载中 | `boolean \| SpinProps` | - | - | - |
| `tableLayout` | 表格元素的 [table-layout](https://developer.mozilla.org/zh-CN/docs/Web/CSS/table-layout) 属性 | `'auto' \| 'fixed'` | - | - | 固定表头/列或设置了 `column.ellipsis` 时,默认值为 `fixed` |
| `tags` | 覆盖默认的表格元素, 参见[TableTags](#TableTags) | `TableTags` | - | - | - |
| `virtual` | 是否开启虚拟滚动 | `boolean` | `false` | - | 需要设置 `scroll.y` |
| `onScroll` | 滚动事件 | `(evt: Event) => void` | - | - | - |
| `onScrolledChange` | 滚动的位置发生变化 | `(startIndex: number, endIndex: number, visibleNodes: TreeNode[]) => void` | - | - |`virtual` 模式下可用 |
Expand Down Expand Up @@ -142,6 +141,20 @@ export type TableColumn<T = any, V = any> =
| `customTrigger` | 自定义展开内容 | `string \| () => VNodeChild)` | - | - | 类型为 `string` 时,对应插槽名 |
| `customMenu` | 自定义表头标题 | `string \| () => VNodeChild)` | - | - | 类型为 `string` 时,对应插槽名 |
#### TableCustomAdditional
```ts
export interface TableCustomAdditional<T = any> {
bodyCell: (data: { column: TableColumn<T>; record: T; rowIndex: number }) => Record<string, any> | undefined
bodyRow: (data: { record: T; rowIndex: number }) => Record<string, any> | undefined
headCell: (data: { column: TableColumn<T> }) => Record<string, any> | undefined
headRow: (data: { columns: TableColumn<T>[] }) => Record<string, any> | undefined
}

```

参考示例:[斑马纹表格](#components-table-demo-CustomAdditional), 返回值可以是任意的原生 dom 属性或者事件。

#### TablePagination

```ts
Expand Down
2 changes: 1 addition & 1 deletion packages/components/table/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ export type {
TableColumnBase,
TableColumnExpandable,
TableColumnSelectable,
TableCustomAdditional,
TablePagination,
TablePaginationPosition,
TableScroll,
TableSize,
TableTags,
TableColumnAlign,
TableColumnFixed,
TableColumnSortable,
Expand Down
12 changes: 5 additions & 7 deletions packages/components/table/src/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import { useSelectable } from './composables/useSelectable'
import { useSortable } from './composables/useSortable'
import { useSticky } from './composables/useSticky'
import { useTableLayout } from './composables/useTableLayout'
import { useTags } from './composables/useTags'
import MainTable from './main/MainTable'
import { renderFooter } from './other/Footer'
import { renderPagination } from './other/Pagination'
Expand All @@ -43,8 +42,8 @@ export default defineComponent({
const config = useGlobalConfig('table')

const autoHeight = computed(() => props.autoHeight ?? config.autoHeight)
const tags = useTags(props)
const getRowKey = useGetRowKey(props, config)
const mergedChildrenKey = computed(() => props.childrenKey ?? config.childrenKey)
const mergedGetKey = useGetRowKey(props, config)
const stickyContext = useSticky(props)
const scrollContext = useScroll(props, autoHeight, stickyContext)
const columnsContext = useColumns(props, slots, config, scrollContext.scrollBarSizeOnFixedHolder)
Expand All @@ -56,7 +55,8 @@ export default defineComponent({

const dataContext = useDataSource(
props,
getRowKey,
mergedChildrenKey,
mergedGetKey,
sortableContext.activeSortable,
filterableContext.activeFilters,
expandableContext.expandedRowKeys,
Expand All @@ -66,12 +66,10 @@ export default defineComponent({

const context = {
props,
mergedPrefixCls,
slots,
config,
locale,
...tags,
getRowKey,
mergedPrefixCls,
...columnsContext,
...scrollContext,
...sortableContext,
Expand Down
9 changes: 5 additions & 4 deletions packages/components/table/src/composables/useDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@ import { type ActiveSortable } from './useSortable'

export function useDataSource(
props: TableProps,
getRowKey: ComputedRef<GetRowKey>,
mergedChildrenKey: ComputedRef<string>,
mergedGetKey: ComputedRef<GetRowKey>,
activeSortable: ActiveSortable,
activeFilters: ComputedRef<ActiveFilter[]>,
expandedRowKeys: Ref<VKey[]>,
mergedPagination: ComputedRef<TablePagination | null>,
): DataSourceContext {
const mergedData = computed(() => {
const { dataSource, childrenKey } = props
const getKey = getRowKey.value
return dataSource.map(record => convertMergeData(record, getKey, childrenKey))
const childrenKey = mergedChildrenKey.value
const getKey = mergedGetKey.value
return props.dataSource.map(record => convertMergeData(record, getKey, childrenKey))
})

const mergedMap = computed(() => {
Expand Down
12 changes: 7 additions & 5 deletions packages/components/table/src/composables/useGetRowKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,22 @@ import { type TableConfig } from '@idux/components/config'
import { type TableProps } from '../types'

export type GetRowKey = (record: unknown) => VKey

/**
* @deprecated please use `useGetKey` instead
*/
export function useGetRowKey(props: TableProps, config: TableConfig): ComputedRef<GetRowKey> {
return computed(() => {
const rowKey = props.rowKey ?? config.rowKey
if (isString(rowKey)) {
const getKey = props.rowKey || props.getKey || config.rowKey || config.getKey
if (isString(getKey)) {
return (record: unknown) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const key = (record as any)[rowKey]
const key = (record as any)[getKey]
if (__DEV__ && key === undefined) {
Logger.warn('components/table', 'Each record in table should have a unique `key` prop.')
}
return key
}
}
return rowKey
return getKey
})
}
8 changes: 4 additions & 4 deletions packages/components/table/src/composables/useScroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import { type StickyContext } from './useSticky'
export function useScroll(
props: TableProps,
autoHeight: ComputedRef<boolean>,
{ isSticky, stickyScrollLeft }: StickyContext,
{ isSticky, setStickyScrollLeft }: StickyContext,
): ScrollContext {
const { scrollHeadRef, scrollBodyRef, scrollFootRef, handleScroll, pingedStart, pingedEnd } =
useScrollRef(stickyScrollLeft)
useScrollRef(setStickyScrollLeft)

__DEV__ &&
props.scroll?.x &&
Expand Down Expand Up @@ -77,7 +77,7 @@ export interface ScrollOptions {
scrollLeft?: number
}

function useScrollRef(stickyScrollLeft: Ref<number>) {
function useScrollRef(setStickyScrollLeft: (value: number) => void) {
const scrollHeadRef = ref<HTMLDivElement>()
const scrollBodyRef = ref<HTMLDivElement>()
const scrollFootRef = ref<HTMLDivElement>()
Expand All @@ -88,7 +88,7 @@ function useScrollRef(stickyScrollLeft: Ref<number>) {
return
}
const { clientWidth, scrollWidth } = scrollBodyElement
stickyScrollLeft.value = (scrollLeft / scrollWidth) * clientWidth || 0
setStickyScrollLeft((scrollLeft / scrollWidth) * clientWidth || 0)
}

const pingedStart = ref(false)
Expand Down

0 comments on commit e79b55b

Please sign in to comment.