Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(components): [table] fixed column supported in grouped header #10096

Merged
merged 10 commits into from
Oct 23, 2022
11 changes: 11 additions & 0 deletions packages/components/table/src/store/watcher.ts
Expand Up @@ -84,8 +84,19 @@ function useWatcher<T>() {
if (!rowKey.value) throw new Error('[ElTable] prop row-key is required')
}

// 更新 fixed
const updateChildFixed = (column: TableColumnCtx<T>) => {
column.children?.forEach((childColumn) => {
childColumn.fixed = column.fixed
updateChildFixed(childColumn)
})
}

// 更新列
const updateColumns = () => {
_columns.value.forEach((column) => {
updateChildFixed(column)
})
fixedColumns.value = _columns.value.filter(
(column) => column.fixed === true || column.fixed === 'left'
)
Expand Down
17 changes: 11 additions & 6 deletions packages/components/table/src/table-body/styles-helper.ts
Expand Up @@ -67,9 +67,11 @@ function useStyles<T>(props: Partial<TableBodyProps<T>>) {
column,
})
}
const fixedStyle = column.isSubColumn
? null
: getFixedColumnOffset(columnIndex, props?.fixed, props.store)
const fixedStyle = getFixedColumnOffset(
columnIndex,
props?.fixed,
props.store
)
ensurePosition(fixedStyle, 'left')
ensurePosition(fixedStyle, 'right')
return Object.assign({}, cellStyles, fixedStyle)
Expand All @@ -81,9 +83,12 @@ function useStyles<T>(props: Partial<TableBodyProps<T>>) {
row: T,
column: TableColumnCtx<T>
) => {
const fixedClasses = column.isSubColumn
? []
: getFixedColumnsClass(ns.b(), columnIndex, props?.fixed, props.store)
const fixedClasses = getFixedColumnsClass(
ns.b(),
columnIndex,
props?.fixed,
props.store
)
const classes = [column.id, column.align, column.className, ...fixedClasses]
const cellClassName = parent?.props.cellClassName
if (typeof cellClassName === 'string') {
Expand Down
30 changes: 13 additions & 17 deletions packages/components/table/src/table-header/style.helper.ts
Expand Up @@ -48,14 +48,12 @@ function useStyle<T>(props: TableHeaderProps<T>) {
column,
})
}
const fixedStyle = column.isSubColumn
? null
: getFixedColumnOffset<T>(
columnIndex,
column.fixed,
props.store,
row as unknown as TableColumnCtx<T>[]
)
const fixedStyle = getFixedColumnOffset<T>(
columnIndex,
column.fixed,
props.store,
row as unknown as TableColumnCtx<T>[]
)
ensurePosition(fixedStyle, 'left')
ensurePosition(fixedStyle, 'right')
return Object.assign({}, headerCellStyles, fixedStyle)
Expand All @@ -67,15 +65,13 @@ function useStyle<T>(props: TableHeaderProps<T>) {
row: T,
column: TableColumnCtx<T>
) => {
const fixedClasses = column.isSubColumn
? []
: getFixedColumnsClass<T>(
ns.b(),
columnIndex,
column.fixed,
props.store,
row as unknown as TableColumnCtx<T>[]
)
const fixedClasses = getFixedColumnsClass<T>(
ns.b(),
columnIndex,
column.fixed,
props.store,
row as unknown as TableColumnCtx<T>[]
)
const classes = [
column.id,
column.order,
Expand Down
57 changes: 35 additions & 22 deletions packages/components/table/src/util.ts
Expand Up @@ -379,6 +379,18 @@ export function createTablePopper(
return popperInstance
}

function getCurrentColumns<T>(column: TableColumnCtx<T>): TableColumnCtx<T>[] {
if (column.children) {
return column.children.flatMap(getCurrentColumns)
tinyfind marked this conversation as resolved.
Show resolved Hide resolved
} else {
return [column]
}
}

function getColSpan<T>(colSpan: number, column: TableColumnCtx<T>) {
return colSpan + column.colSpan
}

export const isFixedColumn = <T>(
index: number,
fixed: string | boolean,
Expand All @@ -387,21 +399,18 @@ export const isFixedColumn = <T>(
) => {
let start = 0
let after = index
const columns = store.states.columns.value
tinyfind marked this conversation as resolved.
Show resolved Hide resolved
if (realColumns) {
if (realColumns[index].colSpan > 1) {
// fixed column not supported in grouped header
return {}
}
// handle group
for (let i = 0; i < index; i++) {
start += realColumns[i].colSpan
}
after = start + realColumns[index].colSpan - 1
// fixed column supported in grouped header
const curColumns = getCurrentColumns(realColumns[index])
const preColumns = columns.slice(0, columns.indexOf(curColumns[0]))

start = preColumns.reduce(getColSpan, 0)
after = start + curColumns.reduce(getColSpan, 0) - 1
} else {
start = index
}
let fixedLayout
const columns = store.states.columns
switch (fixed) {
case 'left':
if (after < store.states.fixedLeafColumnsLength.value) {
Expand All @@ -411,7 +420,7 @@ export const isFixedColumn = <T>(
case 'right':
if (
start >=
columns.value.length - store.states.rightFixedLeafColumnsLength.value
columns.length - store.states.rightFixedLeafColumnsLength.value
) {
fixedLayout = 'right'
}
Expand All @@ -421,7 +430,7 @@ export const isFixedColumn = <T>(
fixedLayout = 'left'
} else if (
start >=
columns.value.length - store.states.rightFixedLeafColumnsLength.value
columns.length - store.states.rightFixedLeafColumnsLength.value
) {
fixedLayout = 'right'
}
Expand All @@ -443,11 +452,16 @@ export const getFixedColumnsClass = <T>(
realColumns?: TableColumnCtx<T>[]
) => {
const classes: string[] = []
const { direction, start } = isFixedColumn(index, fixed, store, realColumns)
const { direction, start, after } = isFixedColumn(
index,
fixed,
store,
realColumns
)
if (direction) {
const isLeft = direction === 'left'
classes.push(`${namespace}-fixed-column--${direction}`)
if (isLeft && start === store.states.fixedLeafColumnsLength.value - 1) {
if (isLeft && after === store.states.fixedLeafColumnsLength.value - 1) {
classes.push('is-last-column')
} else if (
!isLeft &&
Expand Down Expand Up @@ -476,23 +490,22 @@ export const getFixedColumnOffset = <T>(
store: any,
realColumns?: TableColumnCtx<T>[]
) => {
const { direction, start = 0 } = isFixedColumn(
index,
fixed,
store,
realColumns
)
const {
direction,
start = 0,
after = 0,
} = isFixedColumn(index, fixed, store, realColumns)
if (!direction) {
return
}
const styles: any = {}
const isLeft = direction === 'left'
const columns = store.states.columns.value
if (isLeft) {
styles.left = columns.slice(0, index).reduce(getOffset, 0)
styles.left = columns.slice(0, start).reduce(getOffset, 0)
} else {
styles.right = columns
.slice(start + 1)
.slice(after + 1)
.reverse()
.reduce(getOffset, 0)
}
Expand Down