import React from 'react'; import { Table, Switch, ButtonGroup, Button, Avatar } from '@douyinfe/semi-ui'; import * as dateFns from 'date-fns'; const DAY = 24 * 60 * 60 * 1000; const figmaIconUrl = 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/figma-icon.png'; class App extends React.Component { constructor(props) { super(props); const dataTotalSize = 46; const columns = [ { title: '标题', dataIndex: 'name', width: 400, render: (text, record, index) => { return (
{text}
); }, filters: [ { text: 'Semi Design 设计稿', value: 'Semi Design 设计稿', }, { text: 'Semi Pro 设计稿', value: 'Semi Pro 设计稿', }, ], onFilter: (value, record) => record.name.includes(value), }, { title: '大小', dataIndex: 'size', sorter: (a, b) => a.size - b.size > 0 ? 1 : -1, render: (text) => `${text} KB` }, { title: '所有者', dataIndex: 'owner', render: (text, record, index) => { return (
{typeof text === 'string' && text.slice(0, 1)} {text}
); } }, { title: '更新日期', dataIndex: 'updateTime', sorter: (a, b) => a.updateTime - b.updateTime > 0 ? 1 : -1, render: (value) => { return dateFns.format(new Date(value), 'yyyy-MM-dd'); } } ]; this.getData = () => { const data = []; for (let i = 0; i < dataTotalSize; i++) { const isSemiDesign = i % 2 === 0; const randomNumber = (i * 1000) % 199; data.push({ key: '' + i, name: isSemiDesign ? `Semi Design 设计稿${i}.fig` : `Semi Pro 设计稿${i}.fig`, owner: isSemiDesign ? '姜鹏志' : '郝宣', size: randomNumber, updateTime: new Date().valueOf() + randomNumber * DAY, avatarBg: isSemiDesign ? 'grey' : 'red' }); } return data; }; const data = this.getData(); this.data = data; this.mergeColumns = (column, columns, keys = ['dataIndex']) => { columns = [...columns]; columns.forEach((curColumn, index) => { let isTarget = !!(keys && keys.length); for (let key of keys) { if (column[key] !== curColumn[key]) { isTarget = false; break; } } if (isTarget) { columns[index] = { ...curColumn, ...column }; } }); return columns; }; this.filterData = (filters, dataSource) => { dataSource = [...dataSource]; filters.forEach(filter => { let filteredValue = filter.filteredValue; let dataIndex = filter.dataIndex; if (Array.isArray(filteredValue) && filteredValue.length && dataIndex) { dataSource = dataSource.filter( data => filteredValue.filter(value => String(data[dataIndex]).indexOf(value) > -1).length ); } }); return dataSource; }; this.getSelfSorterColumn = columns => { columns = columns || this.state.columns; return columns.filter(column => !!column.sorter)[0]; }; this.getSelfFilterColumns = columns => { columns = columns || this.state.columns; return columns.filter(column => Array.isArray(column.filteredValue) && column.filteredValue.length); }; this.sortData = (sortObj, dataSource) => { let { sorter, sortOrder, dataIndex } = sortObj; if (sorter && sortOrder && typeof sorter !== 'function') { sorter = (a, b) => (a[dataIndex] > b[dataIndex] ? 1 : -1); } if (typeof sorter === 'function') { dataSource = [...dataSource].sort(sorter); if (sortOrder === 'descend') { dataSource = dataSource.reverse(); } } return dataSource; }; this.fetchData = (currentPage = 1, sorter = {}, filters = []) => { // console.log(`FetchData currentPage: `, currentPage); let pagination = { ...this.state.pagination, currentPage }; return new Promise((res, rej) => { setTimeout(() => { let data = [...this.data]; data = this.sortData(sorter, data); data = this.filterData(filters, data); let dataSource = data.slice( (currentPage - 1) * pagination.pageSize, currentPage * pagination.pageSize ); pagination.total = data.length; res({ dataSource, pagination, sorter, filters, }); }, 1500); }); }; this.setPage = (currentPage, sorter, filters) => { if (this.state.loading) { return; } if (typeof currentPage !== 'number') { currentPage = (this.state.pagination && this.state.pagination.currentPage) || 1; } sorter = sorter || this.getSelfSorterColumn(); filters = filters || this.getSelfFilterColumns(); this.setState({ loading: true }); this.fetchData(currentPage, sorter, filters) .then(({ dataSource, pagination, sorter, filters }) => { let columns = [...this.state.columns]; columns = this.mergeColumns(sorter, columns); for (let filterObj of filters) { columns = this.mergeColumns(filterObj, columns); } this.setState({ loading: false, pagination, dataSource, columns, }); }) .catch(err => { console.error(err); this.setState({ loading: false }); }); }; this.toggleFixHeader = checked => { let scroll = { ...this.state.scroll }; if (checked) { scroll.y = 300; } else { scroll.y = null; } this.setState({ scroll }); }; this.toggleFixColumns = checked => { let columns = [...this.state.columns]; let scroll = { ...this.state.scroll }; let expandCellFixed = this.state.expandCellFixed; let rowSelection = this.state.rowSelection; if (checked) { columns[0].fixed = true; if (rowSelection) { rowSelection = { ...rowSelection, fixed: true }; } if (columns.length > 1) { columns[columns.length - 1].fixed = 'right'; } scroll.x = '150%'; expandCellFixed = true; } else { columns.forEach(column => { column.fixed = false; }); scroll.x = null; expandCellFixed = false; if (rowSelection) { rowSelection = { ...rowSelection, fixed: false }; } } this.setState({ rowSelection, expandCellFixed, columns, scroll, }); }; this.toggleRowSelection = checked => { let rowSelection = this.state.rowSelection; // const anyColumnFixed = this.state.columns.some(column => !!column.fixed); if (checked) { rowSelection = { width: 48, fixed: true, onChange: (selectedRowKeys, selectedRows) => console.log( 'Selection changed, selectedRowKeys: ', selectedRowKeys, 'selectedRows: ', selectedRows ), }; } else { rowSelection = null; } this.setState({ rowSelection }); }; this.toggleLoading = checked => { let loading = this.state.loading; if (checked) { loading = true; } else { loading = false; } this.setState({ loading }); }; this.toggleExpandedRowRender = checked => { let expandedRowRender = this.state.expandedRowRender; if (checked) { expandedRowRender = record => { return { children:

{record.description}

, fixed: 'left', }; }; } else { expandedRowRender = null; } this.setState({ expandedRowRender }); }; this.toggleShowSorter = checked => { let columns = [...this.state.columns]; if (checked) { columns.forEach(column => column.dataIndex === 'age' && (column.sorter = true)); } else { columns.forEach(column => (column.sorter = null)); } this.setState({ columns }); }; this.toggleShowFilter = checked => { let columns = [...this.state.columns]; if (checked) { columns.forEach(column => { if (column.dataIndex === 'name') { column.filters = [ { text: '姓名中包含 1', value: '1', }, { text: '姓名中包含 2', value: '2', }, { text: '姓名中包含 3', value: '3', }, ]; column.filteredValue = []; } }); } else { columns.forEach(column => { column.filters = null; column.filteredValue = null; }); } this.setState({ columns }); if (!checked) { this.setPage(null, null, []); } }; this.onChange = (data = {}) => { console.log('Table changed: ', data); let { pagination, sorter, filters } = data; this.setPage(pagination.currentPage, sorter, filters); }; this.onExpandedRowsChange = rows => { console.log('Expanded rows changed to: ', rows); const expandedRowKeys = (Array.isArray(rows) && rows.map(row => row.key)) || []; this.setState({ expandedRowKeys }); }; this.toggleExpandedRowKeys = checked => { let expandedRowKeys = []; if (checked) { let dataSource = [...this.state.dataSource]; expandedRowKeys.push( ...dataSource.reduce((arr, data) => { if (data.key) { arr.push(data.key); } return arr; }, []) ); this.toggleExpandedRowRender(true); } this.setState({ expandedRowKeys }); }; this.toggleBordered = checked => { let bordered = false; if (checked) { bordered = true; } this.setState({ bordered }); }; this.toggleResizable = checked => { let resizable = !!checked || false; this.setState({ resizable, bordered: resizable }); }; this.toggleHideHeader = checked => { let showHeader = true; if (checked) { showHeader = false; } this.setState({ showHeader }); }; this.toggleFooter = checked => { const footer = checked ? dataSource =>

This is footer.

: null; this.setState({ footer }); }; this.toggleTitle = checked => { const title = checked ? 'This is title.' : null; this.setState({ title }); }; this.toggleHidePagination = checked => { let pagination = checked ? false : { currentPage: 1, pageSize: 8, total: data.length, onPageChange: page => this.setPage(page), }; this.setState({ pagination }); }; this.toggleDataSource = checked => { if (checked) { this.setState({ dataSource: [] }); } else { this.setPage(); } }; this.switchPagination = position => { let pagination = this.state.pagination; const defaultPagination = { currentPage: 1, pageSize: 8, total: data.length, onPageChange: page => this.setPage(page), }; const positions = ['bottom', 'top', 'both']; if (position === true || position === false) { pagination = position ? { ...defaultPagination, ...pagination } : false; } else if (positions.includes(position)) { pagination = { ...defaultPagination, ...pagination, position }; } this.setState({ pagination }); }; this.state = { loading: false, columns, scroll: {}, rowSelection: null, expandedRowRender: null, expandCellFixed: false, defaultExpandedRowKeys: [], title: null, footer: null, expandedRowKeys: [], showHeader: true, resizable: false, pagination: { currentPage: 1, pageSize: 8, total: data.length, onPageChange: page => this.setPage(page), }, dataSource: [], }; this.TableSwitch = function TableSwitch({ text, children, checked, onChange, style = { display: 'inline-flex', alignItems: 'center', margin: 5 }, }) { const switchProps = { onChange }; if (checked != null) { switchProps.checked = !!checked; } return ( {text} {children != null ? children : } ); }; } componentDidMount() { this.setPage(1); } render() { let { columns, dataSource, pagination, loading, scroll, rowSelection, expandedRowRender, expandCellFixed, expandedRowKeys, bordered, resizable, title, footer, showHeader, defaultExpandedRowKeys, } = this.state; const wrapStyle = { marginBottom: 15, display: 'flex', justifyContent: 'space-around', flexWrap: 'wrap' }; const TableSwitch = this.TableSwitch; return (
); } } render(App);