mirror of
https://github.com/element-plus/element-plus.git
synced 2024-11-21 01:02:59 +08:00
feat(components): [virtual-table] Table (#7083)
* feat(components): [virtual-table] Table - Add composable for column management. * Update table props
This commit is contained in:
parent
5849909577
commit
9a05d5cdc2
@ -1,4 +1,4 @@
|
||||
import { definePropType } from '@element-plus/utils'
|
||||
import { definePropType, mutable } from '@element-plus/utils'
|
||||
|
||||
import type { CSSProperties } from 'vue'
|
||||
import type { Column, KeyType } from './types'
|
||||
@ -31,6 +31,11 @@ export const dataType = {
|
||||
|
||||
export const expandColumnKey = String
|
||||
|
||||
export const expandKeys = {
|
||||
type: definePropType<KeyType[]>(Array),
|
||||
default: () => mutable([]),
|
||||
} as const
|
||||
|
||||
export const requiredNumber = {
|
||||
type: Number,
|
||||
required: true,
|
||||
@ -38,7 +43,7 @@ export const requiredNumber = {
|
||||
|
||||
export const rowKey = {
|
||||
type: definePropType<KeyType>([String, Number, Symbol]),
|
||||
required: true,
|
||||
default: 'id',
|
||||
} as const
|
||||
|
||||
/**
|
||||
|
@ -20,11 +20,13 @@ export const tableV2HeaderProps = buildProps({
|
||||
},
|
||||
headerHeight: {
|
||||
type: definePropType<number | number[]>([Number, Array]),
|
||||
required: true,
|
||||
default: 50,
|
||||
},
|
||||
rowWidth: requiredNumberType,
|
||||
rowHeight: requiredNumberType,
|
||||
|
||||
rowHeight: {
|
||||
type: Number,
|
||||
default: 50,
|
||||
},
|
||||
height: requiredNumberType,
|
||||
width: requiredNumberType,
|
||||
} as const)
|
||||
|
@ -1,4 +1,16 @@
|
||||
import { buildProps, definePropType } from '@element-plus/utils'
|
||||
import {
|
||||
classType,
|
||||
columns,
|
||||
dataType,
|
||||
expandKeys,
|
||||
fixedDataType,
|
||||
requiredNumber,
|
||||
rowKey,
|
||||
} from './common'
|
||||
import { tableV2RowProps } from './row'
|
||||
import { tableV2HeaderProps } from './header'
|
||||
import { tableV2GridProps } from './grid'
|
||||
|
||||
import type { ExtractPropTypes, StyleValue } from 'vue'
|
||||
import type {
|
||||
@ -53,13 +65,17 @@ export type RowClassNameGetter<T> = (
|
||||
export type ColumnSortHandler<T> = (params: ColumnSortParams<T>) => void
|
||||
|
||||
export const tableV2Props = buildProps({
|
||||
cache: tableV2GridProps.cache,
|
||||
estimatedRowHeight: tableV2RowProps.estimatedRowHeight,
|
||||
rowKey,
|
||||
/**
|
||||
* extra props deriver
|
||||
*/
|
||||
cellProps: {
|
||||
type: definePropType<any | ExtraCellPropGetter<any>>([Object, Function]),
|
||||
},
|
||||
headerClassName: {
|
||||
// Header attributes
|
||||
headerClass: {
|
||||
type: definePropType<string | HeaderClassNameGetter<any>>([
|
||||
String,
|
||||
Function,
|
||||
@ -77,55 +93,54 @@ export const tableV2Props = buildProps({
|
||||
Function,
|
||||
]),
|
||||
},
|
||||
rowClassName: {
|
||||
headerHeight: tableV2HeaderProps.headerHeight,
|
||||
/**
|
||||
* Footer attributes
|
||||
*/
|
||||
footerHeight: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
/**
|
||||
* Row attributes
|
||||
*/
|
||||
rowClass: {
|
||||
type: definePropType<string | RowClassNameGetter<any>>([String, Function]),
|
||||
},
|
||||
rowProps: {
|
||||
type: definePropType<any | ExtractRowPropGetter<any>>([Object, Function]),
|
||||
},
|
||||
|
||||
rowHeight: Number,
|
||||
/**
|
||||
* Data models
|
||||
*/
|
||||
columns: {
|
||||
type: definePropType<Column<any>[]>(Array),
|
||||
required: true,
|
||||
},
|
||||
fixedData: {
|
||||
type: definePropType<any[]>(Array),
|
||||
},
|
||||
data: {
|
||||
type: definePropType<any[]>(Array),
|
||||
},
|
||||
columns,
|
||||
data: dataType,
|
||||
fixedData: fixedDataType,
|
||||
|
||||
/**
|
||||
* Expanded keys
|
||||
*/
|
||||
expandedRowKeys: {
|
||||
type: definePropType<KeyType[]>(Array),
|
||||
},
|
||||
defaultExpandedRowKeys: {
|
||||
type: definePropType<KeyType[]>(Array),
|
||||
},
|
||||
expandColumnKey: tableV2RowProps.expandColumnKey,
|
||||
expandedRowKeys: expandKeys,
|
||||
defaultExpandedRowKeys: expandKeys,
|
||||
|
||||
/**
|
||||
* Attributes
|
||||
*/
|
||||
classNames: {
|
||||
type: definePropType<string | string[]>([String, Array]),
|
||||
},
|
||||
class: classType,
|
||||
disabled: Boolean,
|
||||
footerHeight: {
|
||||
type: definePropType<number | number[]>([Number, Array]),
|
||||
},
|
||||
headerHeight: {
|
||||
type: definePropType<number | number[]>([Number, Array]),
|
||||
},
|
||||
fixed: Boolean,
|
||||
style: {
|
||||
type: definePropType<StyleValue>([String, Array, Object]),
|
||||
},
|
||||
width: requiredNumber,
|
||||
height: Number,
|
||||
maxHeight: Number,
|
||||
|
||||
sortBy: {
|
||||
type: definePropType<{ key: KeyType; order: SortOrder }>(Object),
|
||||
default: () => ({} as { key: KeyType; order: SortOrder }),
|
||||
},
|
||||
|
||||
/**
|
||||
@ -134,6 +149,10 @@ export const tableV2Props = buildProps({
|
||||
onColumnSort: {
|
||||
type: definePropType<ColumnSortParams<any>>(Function),
|
||||
},
|
||||
onExpandedRowsChange: Function,
|
||||
onRowExpand: Function,
|
||||
onScroll: tableV2GridProps.onScroll,
|
||||
rowEventHandlers: tableV2RowProps.rowEventHandlers,
|
||||
} as const)
|
||||
|
||||
export type TableV2Props = ExtractPropTypes<typeof tableV2Props>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { RendererElement, RendererNode, StyleValue, VNode } from 'vue'
|
||||
import type { CSSProperties, RendererElement, RendererNode, VNode } from 'vue'
|
||||
|
||||
import type { sortOrders } from './constants'
|
||||
|
||||
@ -69,7 +69,7 @@ export type Column<T = any> = {
|
||||
maxWidth?: number
|
||||
minWidth?: number
|
||||
resizable?: boolean
|
||||
style?: StyleValue
|
||||
style?: CSSProperties
|
||||
sortable?: boolean
|
||||
width: number
|
||||
/**
|
||||
@ -83,6 +83,8 @@ export type Column<T = any> = {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export type Columns<T> = Column<T>[]
|
||||
|
||||
export type CustomizedCellsType = VNode<
|
||||
RendererNode,
|
||||
RendererElement,
|
||||
|
119
packages/components/table-v2/src/useTable.ts
Normal file
119
packages/components/table-v2/src/useTable.ts
Normal file
@ -0,0 +1,119 @@
|
||||
import { computed, unref } from 'vue'
|
||||
|
||||
import type { CSSProperties, Ref } from 'vue'
|
||||
import type { Column, Columns } from './types'
|
||||
|
||||
const getColumnStyle = (
|
||||
column: Column<any>,
|
||||
fixedColumn: boolean
|
||||
): CSSProperties => {
|
||||
const style = {
|
||||
...(column.style ?? {}),
|
||||
width: column.width,
|
||||
}
|
||||
|
||||
if (!fixedColumn) {
|
||||
if (column.maxWidth) style.maxWidth = column.maxWidth
|
||||
if (column.minWidth) style.maxWidth = column.minWidth
|
||||
}
|
||||
|
||||
return style
|
||||
}
|
||||
|
||||
function useColumns(columns: Ref<Columns<any>>, fixed: Ref<boolean>) {
|
||||
let mappedColumnsCopy: Columns<any> = []
|
||||
|
||||
const mappedColumns = computed(() => {
|
||||
const _columns = unref(columns)
|
||||
const ret = _columns.map((column) => {
|
||||
if (!column.resizable) return column
|
||||
|
||||
let { width } = column
|
||||
if (column.resizable) {
|
||||
const idx = _columns.findIndex(
|
||||
(predicated) => column.key === predicated.key
|
||||
)
|
||||
if (idx >= 0 && _columns[idx].width === column.width) {
|
||||
width = mappedColumnsCopy[idx].width
|
||||
}
|
||||
}
|
||||
return {
|
||||
...column,
|
||||
width,
|
||||
}
|
||||
})
|
||||
|
||||
mappedColumnsCopy = ret
|
||||
return ret
|
||||
})
|
||||
|
||||
const visibleColumns = computed(() => {
|
||||
return unref(mappedColumns).filter((column) => !column.hidden)
|
||||
})
|
||||
|
||||
const fixedColumnsOnLeft = computed(() =>
|
||||
unref(visibleColumns).filter(
|
||||
(column) => column.fixed === 'left' || column.fixed === true
|
||||
)
|
||||
)
|
||||
|
||||
const fixedColumnOnRight = computed(() =>
|
||||
unref(visibleColumns).filter((column) => column.fixed === 'right')
|
||||
)
|
||||
|
||||
const normalColumns = computed(() =>
|
||||
unref(visibleColumns).filter((column) => !column.fixed)
|
||||
)
|
||||
|
||||
const mainColumns = computed(() => {
|
||||
const ret: Columns<any> = []
|
||||
|
||||
unref(fixedColumnsOnLeft).forEach((column) => {
|
||||
ret.push({
|
||||
...column,
|
||||
isPlaceholder: true,
|
||||
})
|
||||
})
|
||||
|
||||
unref(normalColumns).forEach((column) => {
|
||||
ret.push(column)
|
||||
})
|
||||
|
||||
unref(fixedColumnOnRight).forEach((column) => {
|
||||
ret.push({
|
||||
...column,
|
||||
isPlaceholder: true,
|
||||
})
|
||||
})
|
||||
|
||||
return ret
|
||||
})
|
||||
|
||||
const columnsStyle = computed(() => {
|
||||
const columns = unref(mappedColumns)
|
||||
|
||||
return columns.reduce<Record<Column<any>['key'], CSSProperties>>(
|
||||
(style, column) => {
|
||||
style[column.key] = getColumnStyle(column, unref(fixed))
|
||||
return style
|
||||
},
|
||||
{}
|
||||
)
|
||||
})
|
||||
|
||||
return {
|
||||
columns: mappedColumns,
|
||||
columnsStyle,
|
||||
fixedColumnsOnLeft,
|
||||
fixedColumnOnRight,
|
||||
mainColumns,
|
||||
normalColumns,
|
||||
visibleColumns,
|
||||
}
|
||||
}
|
||||
|
||||
function useTable() {
|
||||
// to be filled
|
||||
}
|
||||
|
||||
export { useColumns, useTable }
|
Loading…
Reference in New Issue
Block a user