UNPKG

@ttk/component

Version:

ttk组件库

347 lines (307 loc) 11.5 kB
import React, { PureComponent } from 'react' import VirtualTable from './virtualTable' import { Resizable } from "react-resizable" const ResizeableTitle = props => { const { onResize, width, resizeAble, ...restProps } = props const children = <React.Fragment {...restProps} /> if (!width || !resizeAble) { return children } return ( <Resizable width={width} height={0} handle={resizeHandle => ( <span className={`resizable-handle-${resizeHandle}`} onClick={e => { e.stopPropagation() }} /> )} onResize={onResize} draggableOpts={{ enableUserSelectHack: false }} children={children} /> ) } const getResizeTitle = (cols = [], handerResize) => { const result = [] cols.forEach(col => { const item = { ...col, minWidth: col.children && col.children.length ? Math.max.call(Math, col.title.length * 20, 75 * col.children.length) : col.title.length * 25, title: ( <ResizeableTitle resizeAble={!(col.children && col.children.length)} width={col.width} onResize={handerResize(col.key)} className={'resizable testresizable'} > {col.title} </ResizeableTitle> ) } if (col.children) { delete item.width item.children = getResizeTitle(col.children, handerResize) } result.push(item) }) return result } const resizeCols = (cols, key, size) => { const result = [] cols.forEach(col => { if (col.key === key) { col = { ...col, width: size.width < col.minWidth ? col.minWidth : size.width } } if (col.children) { col.children = resizeCols(col.children, key, size) } result.push(col) }) return result } function flatCol(cols) { cols = cols.flatMap(item => { if (item.children) { item = flatCol(item.children) } return item }) return cols } export default class ColResizeTable extends PureComponent { constructor(props) { super(props) const cols = getResizeTitle(this.props.columns, this.handerResize) const listWidth = getListWidth(cols) const listNums = getListNums(cols) this.state = { columns: cols || [], listWidth, listNums } this.initColsWidth = flatCol(cols) .map(m => m.width || m.minWidth || 0) .reduce((a, b) => a + b, 0) this.tableRef = React.createRef() } handerResize = key => (e, { size }) => { this.setState(({ columns }) => { const nextCols = [...columns] let columnDetails = [], param = {} nextCols.forEach(item => { if (!item.children) { if (item.dataIndex) { if (this.props.NosaveWidth) { columnDetails.push({ fieldName: item.dataIndex, width: item.width, title: item.title, isVisible: true, customDecideVisible: true //控制哪一列显示隐藏 }) } else { columnDetails.push({ fieldName: item.dataIndex, width: item.width, isVisible: true, customDecideVisible: true //控制哪一列显示隐藏 }) } } } else { item.width = 0 item.children.forEach(child => { item.width += child.width columnDetails.push(child) }) columnDetails.push(item) } }) param.columnDetails = columnDetails let that = this, res this.onResizend(function () { res = that.props.onResizeEnd(param) }) let blankIndex = columns.length - 1 while (columns[blankIndex].fixed && columns[blankIndex].fixed == 'right') { blankIndex-- } if (columns[blankIndex].fieldName == 'blank') { const resizePart = findResizeCol(columns, key) const newCols = resizeCols(columns, key, size) newCols[blankIndex].width += (resizePart.width - size.width) if (newCols[blankIndex].width < 0) { newCols[blankIndex].width = 0 } return { columns: newCols } } else { return { columns: resizeCols(columns, key, size) } } }) } render() { const { columns, listWidth } = this.state const { scroll } = this.props const diffWidth = flatCol(columns) .map(m => m.width || m.minWidth || 0) .reduce((a, b) => a + b, 0) - this.initColsWidth const initialWidth = (scroll && listWidth > scroll.w) ? listWidth : scroll.w + 1 const scrollX = diffWidth > 0 ? diffWidth + initialWidth : initialWidth const scrollValue = getScrollValue(scroll) const scrollTop = getScrollTop(scroll) return ( <VirtualTable {...this.props} ref={this.tableRef} style={{ width: `${scroll && scroll.w}px` }} width={scroll && scroll.w} // height={scroll && scroll.y} scroll={{ y: scroll.y, x: scrollX }} columns={columns} rowHeight={this.getRowHeight.bind(this)} scrollTop={scrollTop} initialScrollIndex={scrollValue} /> ) } getRowHeight(index) { let ds = this.props.dataSource if (ds[index].entrys && ds[index].entrys.length > 0) { return 37 * ds[index].entrys.length } return 37 } onResizend = (onResizend) => { let that = this, timeOutTask = function () { that.state.taskPtr && clearTimeout(that.state.taskPtr) let taskPtr = setTimeout(function () { onResizend && onResizend(); }, 500) that.setState({ taskPtr: taskPtr }) } timeOutTask() } componentWillReceiveProps(nextProps) { if (nextProps.columns && nextProps.columns.length) { const newListWidth = getListWidth(nextProps.columns) const newListNums = getListNums(nextProps.columns) const newColumns = getResizeTitle(nextProps.columns, this.handerResize) const { listWidth, listNums } = this.state if ((newListWidth != listWidth || listNums != newListNums) && nextProps.dataSource.length) { this.setState({ listWidth: newListWidth, columns: newColumns }) this.initColsWidth = flatCol(nextProps.columns) .map(m => m.width || m.minWidth || 0) .reduce((a, b) => a + b, 0) } } } componentWillUpdate(nextProps) { const { scroll, matchIndex } = this.props const tableRef = this.tableRef setScrollTop(scroll, tableRef, nextProps.matchIndex) } componentDidUpdate(prevProps) { if (prevProps.matchIndex != this.props.matchIndex) { const { scroll, matchIndex } = this.props setMatchIndex(scroll, this.tableRef, matchIndex) } } componentWillUnmount() { const { scroll, dataSource: ds } = this.props const tableRef = this.tableRef setScrollValue(scroll, ds, tableRef) } } function getMatchOrNot(matchIndex) { const dataInput = document.getElementById('data_input') if (matchIndex >= 0 && (dataInput[`${scroll.class}-matchIndex`] != matchIndex)) { return true } return false } function setMatchIndex(scroll, tableRef, matchIndex) { const dataInput = document.getElementById('data_input') if (!dataInput || !scroll || !scroll.class) return if (!dataInput[`${scroll.class}-searching`]) return tableRef.current.scrollToRow(matchIndex) dataInput[`${scroll.class}-searching`] = false } function setScrollTop(scroll, tableRef, matchIndex) { const dataInput = document.getElementById('data_input') if (!dataInput || !scroll || !scroll.class) return if (matchIndex >= 0 && dataInput[`${scroll.class}-searching`]) { dataInput[`${scroll.class}-scrollTop`] = matchIndex * 37 } else if (tableRef && tableRef.current.bodyRef.current.scrollTop > 0) { dataInput[`${scroll.class}-scrollTop`] = tableRef.current.bodyRef.current.scrollTop } } function getScrollTop(scroll) { const dataInput = document.getElementById('data_input') return dataInput[`${scroll.class}-scrollTop`] } function findResizeCol(cols, key) { let flatC = flatCol(cols) return flatC.filter(o => o.key === key)[0] } function getListWidth(cols, wid = 0) { if (!cols || !cols.length) return 0 return cols.reduce((pre, cur) => { if (cur.children && cur.children.length) { return getListWidth(cur.children, pre) } else { return pre + (cur.width || 0) } }, wid) } function getListNums(cols, nums = 0) { if (!cols || !cols.length) return 0 return cols.reduce((pre, cur) => { if (cur.children && cur.children.length) { return getListNums(cur.children, pre) } else { return pre + (cur.isVisible ? 1 : 0) } }, nums) } function setScrollValue(scroll, ds, tableRef) { const dataInput = document.getElementById('data_input') if (dataInput && scroll && scroll.class && tableRef) { let _position = getLastIndex(ds, tableRef.current.bodyRef.current.scrollTop) dataInput[`${scroll.class}-scrollValue`] = _position || 0 } } function getScrollValue(scroll) { const dataInput = document.getElementById('data_input') if (dataInput) { return dataInput[`${scroll.class}-scrollValue`] || 0 } } function getLastIndex(ds, height) { if (!ds || !ds.length) return undefined let lastIndex for (let i = 0; i < ds.length; i++) { if (height <= 0) { lastIndex = i - 1 break; } if (ds[i].entrys && ds[i].entrys.length > 0) { height -= 37 * ds[i].entrys.length } else { height -= 37 } } return lastIndex }