feat: table add expandIcon

pull/398/head
tangjinzhou 2019-01-05 18:09:27 +08:00
parent ad0727898e
commit 8340a0b684
7 changed files with 91 additions and 58 deletions

View File

@ -50,12 +50,12 @@ export default {
subscribe () {
const { store } = this
this.unsubscribe = store.subscribe(() => {
this.setCheckState()
this.setCheckState(this.$props)
})
},
checkSelection (data, type, byDefaultChecked) {
const { store, getCheckboxPropsByItem, getRecordKey } = this
checkSelection (props, data, type, byDefaultChecked) {
const { store, getCheckboxPropsByItem, getRecordKey } = props || this.$props
// type should be 'every' | 'some'
if (type === 'every' || type === 'some') {
return (
@ -68,9 +68,9 @@ export default {
return false
},
setCheckState () {
const checked = this.getCheckState()
const indeterminate = this.getIndeterminateState()
setCheckState (props) {
const checked = this.getCheckState(props)
const indeterminate = this.getIndeterminateState(props)
this.setState((prevState) => {
const newState = {}
if (indeterminate !== prevState.indeterminate) {
@ -83,23 +83,23 @@ export default {
})
},
getCheckState () {
getCheckState (props) {
const { store, data } = this
let checked
if (!data.length) {
checked = false
} else {
checked = store.getState().selectionDirty
? this.checkSelection(data, 'every', false)
? this.checkSelection(props, data, 'every', false)
: (
this.checkSelection(data, 'every', false) ||
this.checkSelection(data, 'every', true)
this.checkSelection(props, data, 'every', false) ||
this.checkSelection(props, data, 'every', true)
)
}
return checked
},
getIndeterminateState () {
getIndeterminateState (props) {
const { store, data } = this
let indeterminate
if (!data.length) {
@ -107,19 +107,19 @@ export default {
} else {
indeterminate = store.getState().selectionDirty
? (
this.checkSelection(data, 'some', false) &&
!this.checkSelection(data, 'every', false)
this.checkSelection(props, data, 'some', false) &&
!this.checkSelection(props, data, 'every', false)
)
: ((this.checkSelection(data, 'some', false) &&
!this.checkSelection(data, 'every', false)) ||
(this.checkSelection(data, 'some', true) &&
!this.checkSelection(data, 'every', true))
: ((this.checkSelection(props, data, 'some', false) &&
!this.checkSelection(props, data, 'every', false)) ||
(this.checkSelection(props, data, 'some', true) &&
!this.checkSelection(props, data, 'every', true))
)
}
return indeterminate
},
handleSelectAllChagne (e) {
handleSelectAllChange (e) {
const checked = e.target.checked
this.$emit('select', checked ? 'all' : 'removeAll', 0, null)
},
@ -182,7 +182,7 @@ export default {
checked={checked}
indeterminate={indeterminate}
disabled={disabled}
onChange={this.handleSelectAllChagne}
onChange={this.handleSelectAllChange}
/>
{customSelections}
</div>

View File

@ -16,7 +16,7 @@ import Column from './Column'
import ColumnGroup from './ColumnGroup'
import createBodyRow from './createBodyRow'
import { flatArray, treeMap, flatFilter } from './util'
import { initDefaultProps, mergeProps, getOptionProps } from '../_util/props-util'
import { initDefaultProps, mergeProps, getOptionProps, getComponentFromProp, isValidElement } from '../_util/props-util'
import BaseMixin from '../_util/BaseMixin'
import {
TableProps,
@ -437,7 +437,7 @@ export default {
let selectedRowKeys = this.store.getState().selectedRowKeys.concat(defaultSelection)
const key = this.getRecordKey(record, rowIndex)
const { pivot } = this.$data
const rows = this.getFlatCurrentPageData()
const rows = this.getFlatCurrentPageData(this.$props.childrenColumnName)
let realIndex = rowIndex
if (this.$props.expandedRowRender) {
realIndex = rows.findIndex(row => this.getRecordKey(row, rowIndex) === key)
@ -500,10 +500,8 @@ export default {
handleRadioSelect (record, rowIndex, e) {
const checked = e.target.checked
const nativeEvent = e.nativeEvent
const defaultSelection = this.store.getState().selectionDirty ? [] : this.getDefaultSelection()
let selectedRowKeys = this.store.getState().selectedRowKeys.concat(defaultSelection)
const key = this.getRecordKey(record, rowIndex)
selectedRowKeys = [key]
const selectedRowKeys = [key]
this.store.setState({
selectionDirty: true,
})
@ -517,7 +515,7 @@ export default {
},
handleSelectRow (selectionKey, index, onSelectFunc) {
const data = this.getFlatCurrentPageData()
const data = this.getFlatCurrentPageData(this.$props.childrenColumnName)
const defaultSelection = this.store.getState().selectionDirty ? [] : this.getDefaultSelection()
const selectedRowKeys = this.store.getState().selectedRowKeys.concat(defaultSelection)
const changeableRowKeys = data
@ -662,10 +660,10 @@ export default {
},
renderRowSelection (locale) {
const { prefixCls, rowSelection } = this
const { prefixCls, rowSelection, childrenColumnName } = this
const columns = this.columns.concat()
if (rowSelection) {
const data = this.getFlatCurrentPageData().filter((item, index) => {
const data = this.getFlatCurrentPageData(childrenColumnName).filter((item, index) => {
if (rowSelection.getCheckboxProps) {
return !this.getCheckboxPropsByItem(item, index).props.disabled
}
@ -741,6 +739,14 @@ export default {
const key = this.getColumnKey(column, i)
let filterDropdown
let sortButton
let customHeaderCell = column.customHeaderCell
const { slots } = column
let title = column.title
if (title === undefined && slots && slots.title) {
title = this.$slots[slots.title]
title = title && title[0]
}
const sortTitle = this.getColumnTitle(title, {}) || locale.sortTitle
const isSortColumn = this.isSortColumn(column)
if ((column.filters && column.filters.length > 0) || column.filterDropdown) {
const colFilters = key in filters ? filters[key] : []
@ -759,12 +765,6 @@ export default {
)
}
if (column.sorter) {
// const isSortColumn = this.isSortColumn(column)
// if (isSortColumn) {
// column.className = classNames(column.className, {
// [`${prefixCls}-column-sort`]: sortOrder,
// })
// }
const isAscend = isSortColumn && sortOrder === 'ascend'
const isDescend = isSortColumn && sortOrder === 'descend'
sortButton = (
@ -781,7 +781,27 @@ export default {
/>
</div>
)
customHeaderCell = (col) => {
let colProps = {}
// Get original first
if (column.customHeaderCell) {
colProps = {
...column.customHeaderCell(col),
}
}
colProps.on = colProps.on || {}
// Add sorter logic
const onHeaderCellClick = colProps.on.click
colProps.on.click = (...args) => {
this.toggleSortOrder(column)
if (onHeaderCellClick) {
onHeaderCellClick(...args)
}
}
return colProps
}
}
const sortTitleString = sortButton && typeof sortTitle === 'string' ? sortTitle : undefined
return {
...column,
className: classNames(column.className, {
@ -793,29 +813,16 @@ export default {
title: [
<div
key='title'
title={sortButton ? locale.sortTitle : undefined}
title={sortTitleString}
class={sortButton ? `${prefixCls}-column-sorters` : undefined}
onClick={() => this.toggleSortOrder(column)}
>
{this.renderColumnTitle(column.title)}
{sortButton}
</div>,
filterDropdown,
],
customHeaderCell,
}
// column.title = (
// <span key={key}>
// {column.title}
// {sortButton}
// {filterDropdown}
// </span>
// )
// if (sortButton || filterDropdown) {
// column.className = classNames(`${prefixCls}-column-has-filters`, column.className)
// }
// return column
})
},
renderColumnTitle (title) {
@ -829,6 +836,23 @@ export default {
}
return title
},
getColumnTitle (title, parentNode) {
if (!title) {
return
}
if (isValidElement(title)) {
debugger
const props = title.props
if (props && props.children) {
const { children } = props
return this.getColumnTitle(children, props)
}
} else {
return parentNode.title || title
}
},
handleShowSizeChange (current, pageSize) {
const pagination = this.sPagination
pagination.onShowSizeChange(current, pageSize)
@ -939,11 +963,11 @@ export default {
},
getFlatData () {
return flatArray(this.getLocalData())
return flatArray(this.getLocalData(null, false))
},
getFlatCurrentPageData () {
return flatArray(this.getCurrentPageData())
getFlatCurrentPageData (childrenColumnName) {
return flatArray(this.getCurrentPageData(), childrenColumnName)
},
recursiveSort (data, sorterFn) {
@ -954,7 +978,7 @@ export default {
} : item))
},
getLocalData (state) {
getLocalData (state, filter = true) {
const currentState = state || this.$data
const { sFilters: filters } = currentState
const { dataSource } = this.$props
@ -966,7 +990,7 @@ export default {
data = this.recursiveSort(data, sorterFn)
}
//
if (filters) {
if (filter && filters) {
Object.keys(filters).forEach((columnKey) => {
const col = this.findColumn(columnKey)
if (!col) {

View File

@ -49,7 +49,7 @@ const md = {
## How To Use
Specify \`dataSource\` of Table as an array of data.
## Examples
## Examples
`,
}
export default {

View File

@ -44,6 +44,7 @@ const columns = [{
| defaultExpandedRowKeys | Initial expanded row keys | string\[] | - |
| expandedRowKeys | Current expanded row keys | string\[] | - |
| expandedRowRender | Expanded container render for each row | Function(record, index, indent, expanded):VNode\|slot-scope | - |
| expandIcon | Customize row expand Icon. | Function(props):VNode \| slot="expandIcon" slot-scope="props" | - |
| expandRowByClick | Whether to expand row by clicking anywhere in the whole row | boolean | `false` |
| footer | Table footer renderer | Function(currentPageData)\|slot-scope | |
| indentSize | Indent size in pixels of tree data | number | 15 |
@ -120,7 +121,7 @@ One of the Table `columns` prop for describing the table's columns, Column has t
| sortOrder | Order of sorted values: `'ascend'` `'descend'` `false` | boolean\|string | - |
| title | Title of this column | string\|slot | - |
| width | Width of this column | string\|number | - |
| customCell | Set props on per cell | Function(record) | - |
| customCell | Set props on per cell | Function(record, rowIndex) | - |
| customHeaderCell | Set props on per header cell | Function(column) | - |
| onFilter | Callback executed when the confirm filter button is clicked, Use as a `filter` event when using template or jsx | Function | - |
| onFilterDropdownVisibleChange | Callback executed when `filterDropdownVisible` is changed, Use as a `filterDropdownVisible` event when using template or jsx | function(visible) {} | - |

View File

@ -43,7 +43,8 @@ const columns = [{
| defaultExpandAllRows | 初始时,是否展开所有行 | boolean | false |
| defaultExpandedRowKeys | 默认展开的行 | string\[] | - |
| expandedRowKeys | 展开的行,控制属性 | string\[] | - |
| expandedRowRender | 额外的展开行 | Function(record, index, indent, expanded):VNode\|slot-scope| - |
| expandedRowRender | 额外的展开行 | Function(record, index, indent, expanded):VNode \| slot="expandedRowRender" slot-scope="record, index, indent, expanded" | - |
| expandIcon | 自定义展开图标 | Function(props):VNode \| slot="expandIcon" slot-scope="props" | - |
| expandRowByClick | 通过点击行来展开子行 | boolean | `false` |
| footer | 表格尾部 | Function(currentPageData)\|slot-scope | |
| indentSize | 展示树形数据时,每层缩进的宽度,以 px 为单位 | number | 15 |
@ -122,7 +123,7 @@ const columns = [{
| title | 列头显示文字 | string\|slot | - |
| width | 列宽度 | string\|number | - |
| customCell | 设置单元格属性 | Function(record) | - |
| customHeaderCell | 设置头部单元格属性 | Function(column) | - |
| customHeaderCell | 设置头部单元格属性 | Function(column, rowIndex) | - |
| onFilter | 本地模式下,确定筛选的运行函数, 使用template或jsx时作为`filter`事件使用 | Function | - |
| onFilterDropdownVisibleChange | 自定义筛选菜单可见变化时调用使用template或jsx时作为`filterDropdownVisibleChange`事件使用 | function(visible) {} | - |
| slots | 使用columns时可以通过该属性配置支持slot的属性`slots: { filterIcon: 'XXX'}` | object | - |

View File

@ -133,7 +133,8 @@ export declare class Column extends AntdComponent {
* @type Function
*/
customCell: (
record: any
record: any,
rowIndex: number,
) => {
props: object;
attrs: object;

View File

@ -193,6 +193,12 @@ export declare class Table extends AntdComponent {
expanded: boolean
) => any;
/**
* Customize row expand Icon.
* @type Function | ScopedSlot
*/
expandIcon: Function | ScopedSlot;
/**
* Whether to expand row by clicking anywhere in the whole row
* @default false