add vc-table
							parent
							
								
									02028e7749
								
							
						
					
					
						commit
						41f4d3b035
					
				|  | @ -0,0 +1,7 @@ | |||
| import PropTypes from '../vue-types' | ||||
| 
 | ||||
| export const storeShape = PropTypes.shape({ | ||||
|   subscribe: PropTypes.func.isRequired, | ||||
|   setState: PropTypes.func.isRequired, | ||||
|   getState: PropTypes.func.isRequired, | ||||
| }) | ||||
|  | @ -0,0 +1,16 @@ | |||
| 
 | ||||
| import { storeShape } from './PropTypes' | ||||
| export default { | ||||
|   name: 'StoreProvider', | ||||
|   props: { | ||||
|     store: storeShape.isRequired, | ||||
|   }, | ||||
|   provide () { | ||||
|     return { | ||||
|       _store: this.$props, | ||||
|     } | ||||
|   }, | ||||
|   render () { | ||||
|     return this.$slots.default[0] | ||||
|   }, | ||||
| } | ||||
|  | @ -0,0 +1,85 @@ | |||
| import shallowEqual from 'shallowequal' | ||||
| import omit from 'omit.js' | ||||
| import { getOptionProps } from '../props-util' | ||||
| import PropTypes from '../vue-types' | ||||
| 
 | ||||
| function getDisplayName (WrappedComponent) { | ||||
|   return WrappedComponent.name || 'Component' | ||||
| } | ||||
| 
 | ||||
| const defaultMapStateToProps = () => ({}) | ||||
| export default function connect (mapStateToProps) { | ||||
|   const shouldSubscribe = !!mapStateToProps | ||||
|   const finnalMapStateToProps = mapStateToProps || defaultMapStateToProps | ||||
|   return function wrapWithConnect (WrappedComponent) { | ||||
|     const tempProps = omit(WrappedComponent.props || {}, ['store']) | ||||
|     const props = {} | ||||
|     Object.keys(tempProps).forEach(k => { props[k] = PropTypes.any }) | ||||
|     const Connect = { | ||||
|       name: `Connect_${getDisplayName(WrappedComponent)}`, | ||||
|       props, | ||||
|       inject: { | ||||
|         _store: { default: {}}, | ||||
|       }, | ||||
|       data () { | ||||
|         this.store = this._store.store | ||||
|         return { | ||||
|           subscribed: finnalMapStateToProps(this.store.getState(), this.$props), | ||||
|         } | ||||
|       }, | ||||
|       mounted () { | ||||
|         this.trySubscribe() | ||||
|       }, | ||||
| 
 | ||||
|       beforeDestroy () { | ||||
|         this.tryUnsubscribe() | ||||
|       }, | ||||
|       methods: { | ||||
|         handleChange () { | ||||
|           if (!this.unsubscribe) { | ||||
|             return | ||||
|           } | ||||
| 
 | ||||
|           const nextState = finnalMapStateToProps(this.store.getState(), this.$props) | ||||
|           if (!shallowEqual(this.nextState, nextState)) { | ||||
|             this.nextState = nextState | ||||
|             this.subscribed = nextState | ||||
|           } | ||||
|         }, | ||||
| 
 | ||||
|         trySubscribe () { | ||||
|           if (shouldSubscribe) { | ||||
|             this.unsubscribe = this.store.subscribe(this.handleChange) | ||||
|             this.handleChange() | ||||
|           } | ||||
|         }, | ||||
| 
 | ||||
|         tryUnsubscribe () { | ||||
|           if (this.unsubscribe) { | ||||
|             this.unsubscribe() | ||||
|             this.unsubscribe = null | ||||
|           } | ||||
|         }, | ||||
|       }, | ||||
|       render () { | ||||
|         const { $listeners, $slots, $attrs, $scopedSlots, subscribed, store } = this | ||||
|         const props = getOptionProps(this) | ||||
|         const wrapProps = { | ||||
|           props: { | ||||
|             ...props, | ||||
|             ...subscribed, | ||||
|             store, | ||||
|           }, | ||||
|           on: $listeners, | ||||
|           attrs: $attrs, | ||||
|           slots: $slots, | ||||
|           scopedSlots: $scopedSlots, | ||||
|         } | ||||
|         return ( | ||||
|           <WrappedComponent {...wrapProps}/> | ||||
|         ) | ||||
|       }, | ||||
|     } | ||||
|     return Connect | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,30 @@ | |||
| export default function create (initialState) { | ||||
|   let state = initialState | ||||
|   const listeners = [] | ||||
| 
 | ||||
|   function setState (partial) { | ||||
|     state = { ...state, ...partial } | ||||
|     for (let i = 0; i < listeners.length; i++) { | ||||
|       listeners[i]() | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   function getState () { | ||||
|     return state | ||||
|   } | ||||
| 
 | ||||
|   function subscribe (listener) { | ||||
|     listeners.push(listener) | ||||
| 
 | ||||
|     return function unsubscribe () { | ||||
|       const index = listeners.indexOf(listener) | ||||
|       listeners.splice(index, 1) | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return { | ||||
|     setState, | ||||
|     getState, | ||||
|     subscribe, | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,5 @@ | |||
| export { default as Provider } from './Provider' | ||||
| 
 | ||||
| export { default as connect } from './connect' | ||||
| 
 | ||||
| export { default as create } from './create' | ||||
|  | @ -1,3 +1,5 @@ | |||
| @import 'normalize.css'; | ||||
| 
 | ||||
| @tablePrefixCls: rc-table; | ||||
| @text-color             : #666; | ||||
| @font-size-base         : 12px; | ||||
|  |  | |||
|  | @ -0,0 +1,220 @@ | |||
| /*! normalize.css v3.0.1 | MIT License | git.io/normalize */ | ||||
| 
 | ||||
| html { | ||||
|     font-family: sans-serif; | ||||
|     -ms-text-size-adjust: 100%; | ||||
|     -webkit-text-size-adjust: 100% | ||||
| } | ||||
| 
 | ||||
| body { | ||||
|     margin: 0 | ||||
| } | ||||
| 
 | ||||
| article, | ||||
| aside, | ||||
| details, | ||||
| figcaption, | ||||
| figure, | ||||
| footer, | ||||
| header, | ||||
| hgroup, | ||||
| main, | ||||
| nav, | ||||
| section, | ||||
| summary { | ||||
|     display: block | ||||
| } | ||||
| 
 | ||||
| audio, | ||||
| canvas, | ||||
| progress, | ||||
| video { | ||||
|     display: inline-block; | ||||
|     vertical-align: baseline | ||||
| } | ||||
| 
 | ||||
| audio:not([controls]) { | ||||
|     display: none; | ||||
|     height: 0 | ||||
| } | ||||
| 
 | ||||
| [hidden], | ||||
| template { | ||||
|     display: none | ||||
| } | ||||
| 
 | ||||
| a { | ||||
|     background: 0 0 | ||||
| } | ||||
| 
 | ||||
| a:active, | ||||
| a:hover { | ||||
|     outline: 0 | ||||
| } | ||||
| 
 | ||||
| abbr[title] { | ||||
|     border-bottom: 1px dotted | ||||
| } | ||||
| 
 | ||||
| b, | ||||
| strong { | ||||
|     font-weight: 700 | ||||
| } | ||||
| 
 | ||||
| dfn { | ||||
|     font-style: italic | ||||
| } | ||||
| 
 | ||||
| h1 { | ||||
|     font-size: 2em; | ||||
|     margin: .67em 0 | ||||
| } | ||||
| 
 | ||||
| mark { | ||||
|     background: #ff0; | ||||
|     color: #000 | ||||
| } | ||||
| 
 | ||||
| small { | ||||
|     font-size: 80% | ||||
| } | ||||
| 
 | ||||
| sub, | ||||
| sup { | ||||
|     font-size: 75%; | ||||
|     line-height: 0; | ||||
|     position: relative; | ||||
|     vertical-align: baseline | ||||
| } | ||||
| 
 | ||||
| sup { | ||||
|     top: -.5em | ||||
| } | ||||
| 
 | ||||
| sub { | ||||
|     bottom: -.25em | ||||
| } | ||||
| 
 | ||||
| img { | ||||
|     border: 0 | ||||
| } | ||||
| 
 | ||||
| svg:not(:root) { | ||||
|     overflow: hidden | ||||
| } | ||||
| 
 | ||||
| figure { | ||||
|     margin: 1em 40px | ||||
| } | ||||
| 
 | ||||
| hr { | ||||
|     -moz-box-sizing: content-box; | ||||
|     box-sizing: content-box; | ||||
|     height: 0 | ||||
| } | ||||
| 
 | ||||
| pre { | ||||
|     overflow: auto | ||||
| } | ||||
| 
 | ||||
| code, | ||||
| kbd, | ||||
| pre, | ||||
| samp { | ||||
|     font-family: monospace, monospace; | ||||
|     font-size: 1em | ||||
| } | ||||
| 
 | ||||
| button, | ||||
| input, | ||||
| optgroup, | ||||
| select, | ||||
| textarea { | ||||
|     color: inherit; | ||||
|     font: inherit; | ||||
|     margin: 0 | ||||
| } | ||||
| 
 | ||||
| button { | ||||
|     overflow: visible | ||||
| } | ||||
| 
 | ||||
| button, | ||||
| select { | ||||
|     text-transform: none | ||||
| } | ||||
| 
 | ||||
| button, | ||||
| html input[type=button], | ||||
| input[type=reset], | ||||
| input[type=submit] { | ||||
|     -webkit-appearance: button; | ||||
|     cursor: pointer | ||||
| } | ||||
| 
 | ||||
| button[disabled], | ||||
| html input[disabled] { | ||||
|     cursor: default | ||||
| } | ||||
| 
 | ||||
| button::-moz-focus-inner, | ||||
| input::-moz-focus-inner { | ||||
|     border: 0; | ||||
|     padding: 0 | ||||
| } | ||||
| 
 | ||||
| input { | ||||
|     line-height: normal | ||||
| } | ||||
| 
 | ||||
| input[type=checkbox], | ||||
| input[type=radio] { | ||||
|     box-sizing: border-box; | ||||
|     padding: 0 | ||||
| } | ||||
| 
 | ||||
| input[type=number]::-webkit-inner-spin-button, | ||||
| input[type=number]::-webkit-outer-spin-button { | ||||
|     height: auto | ||||
| } | ||||
| 
 | ||||
| input[type=search] { | ||||
|     -webkit-appearance: textfield; | ||||
|     -moz-box-sizing: content-box; | ||||
|     -webkit-box-sizing: content-box; | ||||
|     box-sizing: content-box | ||||
| } | ||||
| 
 | ||||
| input[type=search]::-webkit-search-cancel-button, | ||||
| input[type=search]::-webkit-search-decoration { | ||||
|     -webkit-appearance: none | ||||
| } | ||||
| 
 | ||||
| fieldset { | ||||
|     border: 1px solid silver; | ||||
|     margin: 0 2px; | ||||
|     padding: .35em .625em .75em | ||||
| } | ||||
| 
 | ||||
| legend { | ||||
|     border: 0; | ||||
|     padding: 0 | ||||
| } | ||||
| 
 | ||||
| textarea { | ||||
|     overflow: auto | ||||
| } | ||||
| 
 | ||||
| optgroup { | ||||
|     font-weight: 700 | ||||
| } | ||||
| 
 | ||||
| table { | ||||
|     border-collapse: collapse; | ||||
|     border-spacing: 0 | ||||
| } | ||||
| 
 | ||||
| td, | ||||
| th { | ||||
|     padding: 0 | ||||
| } | ||||
|  | @ -1,70 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import Animate from 'rc-animate'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| import 'rc-table/assets/animation.less'; | ||||
| 
 | ||||
| const AnimateBody = (props) => | ||||
|   <Animate transitionName="move" component="tbody" {...props} />; | ||||
| 
 | ||||
| class Demo extends React.Component { | ||||
|   constructor(props) { | ||||
|     super(props); | ||||
|     this.columns = [ | ||||
|       { title: 'title1', dataIndex: 'a', key: 'a', width: 100 }, | ||||
|       { id: '123', title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, | ||||
|       { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, | ||||
|       { | ||||
|         title: 'Operations', dataIndex: '', key: 'd', render: (text, record) => | ||||
|         <a onClick={e => this.onDelete(record.key, e)} href="#">Delete</a>, | ||||
|       }, | ||||
|     ]; | ||||
|     this.state = { | ||||
|       data: [ | ||||
|         { a: '123', key: '1' }, | ||||
|         { a: 'cdd', b: 'edd', key: '2' }, | ||||
|         { a: '1333', c: 'eee', key: '3' }, | ||||
|       ], | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   onDelete(key, e) { | ||||
|     console.log('Delete', key); | ||||
|     e.preventDefault(); | ||||
|     const data = this.state.data.filter(item => item.key !== key); | ||||
|     this.setState({ data }); | ||||
|   } | ||||
| 
 | ||||
|   onAdd() { | ||||
|     const data = [...this.state.data]; | ||||
|     data.push({ | ||||
|       a: 'new data', | ||||
|       b: 'new data', | ||||
|       c: 'new data', | ||||
|       key: Date.now(), | ||||
|     }); | ||||
|     this.setState({ data }); | ||||
|   } | ||||
| 
 | ||||
|   render() { | ||||
|     return ( | ||||
|       <div style={{ margin: 20 }}> | ||||
|         <h2>Table row with animation</h2> | ||||
|         <button onClick={() => this.onAdd()}>添加</button> | ||||
|         <Table | ||||
|           columns={this.columns} | ||||
|           data={this.state.data} | ||||
|           components={{ | ||||
|             body: { wrapper: AnimateBody }, | ||||
|           }} | ||||
|         /> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| ReactDOM.render( | ||||
|   <Demo />, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,8 +1,6 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| import Table from '../index' | ||||
| import '../assets/index.less' | ||||
| 
 | ||||
| const columns = [{ | ||||
|   title: 'Name', | ||||
|  | @ -24,7 +22,7 @@ const columns = [{ | |||
|   dataIndex: 'operation', | ||||
|   key: 'x', | ||||
|   width: 150, | ||||
| }]; | ||||
| }] | ||||
| 
 | ||||
| const data = [{ | ||||
|   key: 1, | ||||
|  | @ -75,13 +73,21 @@ const data = [{ | |||
|   name: 'b', | ||||
|   age: 32, | ||||
|   address: 'I am b', | ||||
| }]; | ||||
| }] | ||||
| 
 | ||||
| function onExpand(expanded, record) { | ||||
|   console.log('onExpand', expanded, record); | ||||
| function onExpand (expanded, record) { | ||||
|   console.log('onExpand', expanded, record) | ||||
| } | ||||
| export default { | ||||
|   render () { | ||||
|     return ( | ||||
|       <Table | ||||
|         defaultExpandAllRows | ||||
|         columns={columns} | ||||
|         data={data} | ||||
|         indentSize={30} | ||||
|         onExpand={onExpand} /> | ||||
|     ) | ||||
|   }, | ||||
| } | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <Table defaultExpandAllRows columns={columns} data={data} indentSize={30} onExpand={onExpand} />, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  |  | |||
|  | @ -1,45 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: 'title1', dataIndex: 'a', | ||||
|     className: 'a', | ||||
|     key: 'a', width: 100 }, | ||||
|   { id: '123', title: 'title2', dataIndex: 'b', | ||||
|     className: 'b', | ||||
|     key: 'b', width: 100 }, | ||||
|   { title: 'title3', dataIndex: 'c', | ||||
|     className: 'c', | ||||
|     key: 'c', width: 200 }, | ||||
|   { | ||||
|     title: 'Operations', dataIndex: '', | ||||
|     className: 'd', | ||||
|     key: 'd', render() { | ||||
|       return <a href="#">Operations</a>; | ||||
|     }, | ||||
|   }, | ||||
| ]; | ||||
| 
 | ||||
| const data = [ | ||||
|   { a: '123', key: '1' }, | ||||
|   { a: 'cdd', b: 'edd', key: '2' }, | ||||
|   { a: '1333', c: 'eee', d: 2, key: '3' }, | ||||
| ]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>rowClassName and className</h2> | ||||
|     <Table | ||||
|       columns={columns} | ||||
|       rowClassName={(record, i) => `row-${i}`} | ||||
|       expandedRowRender={record => <p>extra: {record.a}</p>} | ||||
|       expandedRowClassName={(record, i) => `ex-row-${i}`} | ||||
|       data={data} | ||||
|       className="table" | ||||
|     /> | ||||
|   </div>, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,107 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: '手机号', dataIndex: 'a', colSpan: 2, width: 100, key: 'a', render(o, row, index) { | ||||
|     const obj = { | ||||
|       children: o, | ||||
|       props: {}, | ||||
|     }; | ||||
|     // 设置第一行为链接
 | ||||
|     if (index === 0) { | ||||
|       obj.children = <a href="#">{o}</a>; | ||||
|     } | ||||
|     // 第5行合并两列
 | ||||
|     if (index === 4) { | ||||
|       obj.props.colSpan = 2; | ||||
|     } | ||||
| 
 | ||||
|     if (index === 5) { | ||||
|       obj.props.colSpan = 6; | ||||
|     } | ||||
|     return obj; | ||||
|   } }, | ||||
|   { title: '电话', dataIndex: 'b', colSpan: 0, width: 100, key: 'b', render(o, row, index) { | ||||
|     const obj = { | ||||
|       children: o, | ||||
|       props: {}, | ||||
|     }; | ||||
|     // 列合并掉的表格设置colSpan=0,不会去渲染
 | ||||
|     if (index === 4 || index === 5) { | ||||
|       obj.props.colSpan = 0; | ||||
|     } | ||||
|     return obj; | ||||
|   } }, | ||||
|   { title: 'Name', dataIndex: 'c', width: 100, key: 'c', render(o, row, index) { | ||||
|     const obj = { | ||||
|       children: o, | ||||
|       props: {}, | ||||
|     }; | ||||
| 
 | ||||
|     if (index === 5) { | ||||
|       obj.props.colSpan = 0; | ||||
|     } | ||||
|     return obj; | ||||
|   } }, | ||||
|   { title: 'Address', dataIndex: 'd', width: 200, key: 'd', render(o, row, index) { | ||||
|     const obj = { | ||||
|       children: o, | ||||
|       props: {}, | ||||
|     }; | ||||
|     if (index === 0) { | ||||
|       obj.props.rowSpan = 2; | ||||
|     } | ||||
|     if (index === 1 || index === 5) { | ||||
|       obj.props.rowSpan = 0; | ||||
|     } | ||||
| 
 | ||||
|     return obj; | ||||
|   } }, | ||||
|   { title: 'Gender', dataIndex: 'e', width: 200, key: 'e', render(o, row, index) { | ||||
|     const obj = { | ||||
|       children: o, | ||||
|       props: {}, | ||||
|     }; | ||||
|     if (index === 5) { | ||||
|       obj.props.colSpan = 0; | ||||
|     } | ||||
|     return obj; | ||||
|   } }, | ||||
|   { | ||||
|     title: 'Operations', dataIndex: '', key: 'f', | ||||
|     render(o, row, index) { | ||||
|       if (index === 5) { | ||||
|         return { | ||||
|           props: { | ||||
|             colSpan: 0, | ||||
|           }, | ||||
|         }; | ||||
|       } | ||||
|       return <a href="#">Operations</a>; | ||||
|     }, | ||||
|   }, | ||||
| ]; | ||||
| 
 | ||||
| const data = [ | ||||
|   { a: '13812340987', b: '0571-12345678', c: '张三', d: '文一西路', e: 'Male', key: '1' }, | ||||
|   { a: '13812340986', b: '0571-98787658', c: '张夫人', d: '文一西路', e: 'Female', key: '2' }, | ||||
|   { a: '13812988888', b: '0571-099877', c: '李四', d: '文二西路', e: 'Male', key: '3' }, | ||||
|   { a: '1381200008888', b: '0571-099877', c: '王五', d: '文二西路', e: 'Male', key: '4' }, | ||||
|   { a: '0571-88888110', c: '李警官', d: '武林门', e: 'Male', key: '5' }, | ||||
|   { a: '资料统计完毕于xxxx年xxx月xxx日', key: '6' }, | ||||
| ]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>colSpan & rowSpan</h2> | ||||
|     <Table | ||||
|       columns={columns} | ||||
|       data={data} | ||||
|       className="table" | ||||
|     /> | ||||
|   </div>, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,84 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| import { Resizable } from 'react-resizable'; | ||||
| import 'react-resizable/css/styles.css'; | ||||
| 
 | ||||
| const ResizeableTitle = (props) => { | ||||
|   const { onResize, width, ...restProps } = props; | ||||
| 
 | ||||
|   if (!width) { | ||||
|     return <th {...restProps} />; | ||||
|   } | ||||
| 
 | ||||
|   return ( | ||||
|     <Resizable width={width} height={0} onResize={onResize}> | ||||
|       <th {...restProps} /> | ||||
|     </Resizable> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| ResizeableTitle.propTypes = { | ||||
|   onResize: PropTypes.func.isRequired, | ||||
|   width: PropTypes.number, | ||||
| }; | ||||
| 
 | ||||
| class Demo extends React.Component { | ||||
|   state = { | ||||
|     columns: [ | ||||
|       { title: 'title1', dataIndex: 'a', key: 'a', width: 100 }, | ||||
|       { id: '123', title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, | ||||
|       { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, | ||||
|       { | ||||
|         title: 'Operations', dataIndex: '', key: 'd', render() { | ||||
|           return <a href="#">Operations</a>; | ||||
|         }, | ||||
|       }, | ||||
|     ], | ||||
|   } | ||||
| 
 | ||||
|   components = { | ||||
|     header: { | ||||
|       cell: ResizeableTitle, | ||||
|     }, | ||||
|   } | ||||
| 
 | ||||
|   data = [ | ||||
|     { a: '123', key: '1' }, | ||||
|     { a: 'cdd', b: 'edd', key: '2' }, | ||||
|     { a: '1333', c: 'eee', d: 2, key: '3' }, | ||||
|   ] | ||||
| 
 | ||||
|   handleResize = index => (e, { size }) => { | ||||
|     this.setState(({ columns }) => { | ||||
|       const nextColumns = [...columns]; | ||||
|       nextColumns[index] = { | ||||
|         ...nextColumns[index], | ||||
|         width: size.width, | ||||
|       }; | ||||
|       return { columns: nextColumns }; | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   render() { | ||||
|     const columns = this.state.columns.map((col, index) => ({ | ||||
|       ...col, | ||||
|       onHeaderCell: (column) => ({ | ||||
|         width: column.width, | ||||
|         onResize: this.handleResize(index), | ||||
|       }), | ||||
|     })); | ||||
| 
 | ||||
|     return ( | ||||
|       <div> | ||||
|         <h2>Integrate with react-resizable</h2> | ||||
|         <Table components={this.components} columns={columns} data={this.data} /> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| ReactDOM.render(<Demo />, document.getElementById('__react-content')); | ||||
|  | @ -1,111 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import Menu, { Item, Divider } from 'rc-menu'; | ||||
| import DropDown from 'rc-dropdown'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| import 'rc-dropdown/assets/index.css'; | ||||
| import 'rc-menu/assets/index.css'; | ||||
| 
 | ||||
| const data = []; | ||||
| for (let i = 0; i < 10; i++) { | ||||
|   data.push({ | ||||
|     key: i, | ||||
|     a: `a${i}`, | ||||
|     b: `b${i}`, | ||||
|     c: `c${i}`, | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| class Demo extends React.Component { | ||||
|   state = { | ||||
|     visible: false, | ||||
|   } | ||||
| 
 | ||||
|   filters = [] | ||||
| 
 | ||||
|   handleVisibleChange = (visible) => { | ||||
|     this.setState({ visible }); | ||||
|   } | ||||
| 
 | ||||
|   handleSelect = (selected) => { | ||||
|     this.filters.push(selected); | ||||
|   } | ||||
| 
 | ||||
|   handleDeselect = (key) => { | ||||
|     const index = this.filters.indexOf(key); | ||||
|     if (index !== -1) { | ||||
|       this.filters.splice(index, 1); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   confirmFilter = () => { | ||||
|     console.log(this.filters.join(',')); | ||||
|     this.setState({ | ||||
|       visible: false, | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   render() { | ||||
|     const menu = ( | ||||
|       <Menu | ||||
|         style={{ width: 200 }} | ||||
|         multiple | ||||
|         onSelect={this.handleSelect} | ||||
|         onDeselect={this.handleDeselect} | ||||
|       > | ||||
|         <Item key="1">one</Item> | ||||
|         <Item key="2">two</Item> | ||||
|         <Item key="3">three</Item> | ||||
|         <Divider /> | ||||
|         <Item disabled> | ||||
|           <button | ||||
|             style={{ | ||||
|               cursor: 'pointer', | ||||
|               color: '#000', | ||||
|               pointerEvents: 'visible', | ||||
|             }} | ||||
|             onClick={this.confirmFilter} | ||||
|           >确定</button> | ||||
|         </Item> | ||||
|       </Menu> | ||||
|     ); | ||||
| 
 | ||||
|     const columns = [ | ||||
|       { | ||||
|         title: ( | ||||
|           <div> | ||||
|             title1 | ||||
|             <DropDown | ||||
|               trigger={['click']} | ||||
|               onVisibleChange={this.handleVisibleChange} | ||||
|               visible={this.state.visible} | ||||
|               overlay={menu} | ||||
|             > | ||||
|               <a href="#">filter</a> | ||||
|             </DropDown> | ||||
|           </div> | ||||
|         ), key: 'a', dataIndex: 'a', width: 100, | ||||
|       }, | ||||
|       { title: 'title2', key: 'b', dataIndex: 'b', width: 100 }, | ||||
|       { title: 'title3', key: 'c', dataIndex: 'c', width: 200 }, | ||||
|     ]; | ||||
| 
 | ||||
|     return ( | ||||
|       <Table | ||||
|         columns={columns} | ||||
|         data={data} | ||||
|         rowKey={record => record.key} | ||||
|       /> | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>use dropdown</h2> | ||||
|     <Demo /> | ||||
|   </div>, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,114 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const tableData = [ | ||||
|   { key: 0, a: '123' }, | ||||
|   { key: 1, a: 'cdd', b: 'edd' }, | ||||
|   { key: 2, a: '1333', c: 'eee', d: 2 }, | ||||
| ]; | ||||
| 
 | ||||
| class Demo extends React.Component { | ||||
|   state = { | ||||
|     data: tableData, | ||||
|     expandedRowKeys: [], | ||||
|     expandIconAsCell: true, | ||||
|     expandRowByClick: false, | ||||
|   } | ||||
| 
 | ||||
|   onExpand = (expanded, record) => { | ||||
|     console.log('onExpand', expanded, record); | ||||
|   } | ||||
| 
 | ||||
|   onExpandedRowsChange = (rows) => { | ||||
|     this.setState({ | ||||
|       expandedRowKeys: rows, | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   onExpandIconAsCellChange = (e) => { | ||||
|     this.setState({ | ||||
|       expandIconAsCell: e.target.checked, | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   onExpandRowByClickChange = (e) => { | ||||
|     this.setState({ | ||||
|       expandRowByClick: e.target.checked, | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   columns = [ | ||||
|     { title: 'title 1', dataIndex: 'a', key: 'a', width: 100 }, | ||||
|     { title: 'title 2', dataIndex: 'b', key: 'b', width: 100 }, | ||||
|     { title: 'title 3', dataIndex: 'c', key: 'c', width: 200 }, | ||||
|     { title: 'Operation', dataIndex: '', key: 'x', render: this.renderAction }, | ||||
|   ] | ||||
| 
 | ||||
|   toggleButton() { | ||||
|     if (this.state.expandedRowKeys.length) { | ||||
|       const closeAll = () => this.setState({ expandedRowKeys: [] }); | ||||
|       return <button onClick={closeAll}>Close All</button>; | ||||
|     } | ||||
|     const openAll = () => this.setState({ expandedRowKeys: [0, 1, 2] }); | ||||
|     return <button onClick={openAll}>Expand All</button>; | ||||
|   } | ||||
| 
 | ||||
|   remove(index) { | ||||
|     const data = this.state.data; | ||||
|     data.splice(index, 1); | ||||
|     this.setState({ data }); | ||||
|   } | ||||
| 
 | ||||
|   expandedRowRender(record) { | ||||
|     // console.log(record);
 | ||||
|     return <p>extra: {record.a}</p>; | ||||
|   } | ||||
| 
 | ||||
|   renderAction(o, row, index) { | ||||
|     return <a href="#" onClick={() => this.remove(index)}>Delete</a>; | ||||
|   } | ||||
| 
 | ||||
|   render() { | ||||
|     const { expandIconAsCell, expandRowByClick, expandedRowKeys, data } = this.state; | ||||
|     return ( | ||||
|       <div> | ||||
|         {this.toggleButton()} | ||||
|         <span style={{ display: 'inline-block', width: 20 }} /> | ||||
|         <input | ||||
|           type="checkbox" | ||||
|           checked={expandIconAsCell} | ||||
|           onChange={this.onExpandIconAsCellChange} | ||||
|         /> | ||||
|         expandIconAsCell | ||||
|         <span style={{ display: 'inline-block', width: 20 }} /> | ||||
|         <input | ||||
|           type="checkbox" | ||||
|           checked={expandRowByClick} | ||||
|           onChange={this.onExpandRowByClickChange} | ||||
|         /> | ||||
|         expandRowByClick | ||||
|         <Table | ||||
|           columns={this.columns} | ||||
|           expandIconAsCell={expandIconAsCell} | ||||
|           expandRowByClick={expandRowByClick} | ||||
|           expandedRowRender={this.expandedRowRender} | ||||
|           expandedRowKeys={expandedRowKeys} | ||||
|           onExpandedRowsChange={this.onExpandedRowsChange} | ||||
|           onExpand={this.onExpand} | ||||
|           data={data} | ||||
|         /> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>expandedRowRender</h2> | ||||
|     <Demo /> | ||||
|   </div>, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,46 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: 'title1', dataIndex: 'a', key: 'a', width: 100, fixed: 'left' }, | ||||
|   { title: 'title2', dataIndex: 'b', key: 'b', width: 100, fixed: 'left' }, | ||||
|   { title: 'title3', dataIndex: 'c', key: 'c' }, | ||||
|   { title: 'title4', dataIndex: 'b', key: 'd' }, | ||||
|   { title: 'title5', dataIndex: 'b', key: 'e' }, | ||||
|   { title: 'title6', dataIndex: 'b', key: 'f', | ||||
|     render: () => <div style={{ height: '40px', lineHeight: '40px' }}>我很高</div> }, | ||||
|   { title: 'title7', dataIndex: 'b', key: 'g' }, | ||||
|   { title: 'title8', dataIndex: 'b', key: 'h' }, | ||||
|   { title: 'title9', dataIndex: 'b', key: 'i' }, | ||||
|   { title: 'title10', dataIndex: 'b', key: 'j' }, | ||||
|   { title: 'title11', dataIndex: 'b', key: 'k' }, | ||||
|   { title: 'title12', dataIndex: 'b', key: 'l', width: 100, fixed: 'right' }, | ||||
| ]; | ||||
| 
 | ||||
| const data = [ | ||||
|   { a: '123', b: 'xxxxxxxx', d: 3, key: '1', title: 'hello' }, | ||||
|   { a: 'cdd', b: 'edd12221', d: 3, key: '2', title: 'hello' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '3', title: 'hello' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '4', title: 'hello' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '5', title: 'hello' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '6', title: 'hello' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '7', title: 'hello' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '8', title: 'hello' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '9', title: 'hello' }, | ||||
| ]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div style={{ width: 800 }}> | ||||
|     <h2>Fixed columns</h2> | ||||
|     <Table | ||||
|       columns={columns} | ||||
|       expandedRowRender={record => record.title} | ||||
|       expandIconAsCell | ||||
|       scroll={{ x: 1200 }} | ||||
|       data={data} | ||||
|     /> | ||||
|   </div> | ||||
| , document.getElementById('__react-content')); | ||||
|  | @ -1,45 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: 'title1', dataIndex: 'a', key: 'a', width: 100, fixed: 'left' }, | ||||
|   { title: 'title2', dataIndex: 'b', key: 'b', width: 100, fixed: 'left' }, | ||||
|   { title: 'title3', dataIndex: 'c', key: 'c' }, | ||||
|   { title: 'title4', dataIndex: 'b', key: 'd' }, | ||||
|   { title: 'title5', dataIndex: 'b', key: 'e' }, | ||||
|   { title: 'title6', dataIndex: 'b', key: 'f' }, | ||||
|   { title: <div>title7<br /><br /><br />Hello world!</div>, dataIndex: 'b', key: 'g' }, | ||||
|   { title: 'title8', dataIndex: 'b', key: 'h' }, | ||||
|   { title: 'title9', dataIndex: 'b', key: 'i' }, | ||||
|   { title: 'title10', dataIndex: 'b', key: 'j' }, | ||||
|   { title: 'title11', dataIndex: 'b', key: 'k' }, | ||||
|   { title: 'title12', dataIndex: 'b', key: 'l', width: 100, fixed: 'right' }, | ||||
| ]; | ||||
| 
 | ||||
| const data = [ | ||||
|   { a: '123', b: 'xxxxxxxx', d: 3, key: '1' }, | ||||
|   { a: 'cdd', b: 'edd12221', d: 3, key: '2' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '3' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '4' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '5' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '6' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '7' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '8' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '9' }, | ||||
| ]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div style={{ width: 800 }}> | ||||
|     <h2>Fixed columns</h2> | ||||
|     <Table | ||||
|       columns={columns} | ||||
|       expandedRowRender={record => record.title} | ||||
|       expandIconAsCell | ||||
|       scroll={{ x: 1200 }} | ||||
|       data={data} | ||||
|     /> | ||||
|   </div> | ||||
| , document.getElementById('__react-content')); | ||||
|  | @ -1,39 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: 'title1', dataIndex: 'a', key: 'a', width: 100, fixed: 'left' }, | ||||
|   { title: 'title2', dataIndex: 'b', key: 'b', width: 100, fixed: 'left' }, | ||||
|   { title: 'title3', dataIndex: 'c', key: 'c', width: 150 }, | ||||
|   { title: 'title4', dataIndex: 'c', key: 'd', width: 150 }, | ||||
|   { title: 'title5', dataIndex: 'c', key: 'e', width: 150 }, | ||||
|   { title: 'title6', dataIndex: 'c', key: 'f', width: 150 }, | ||||
|   { title: 'title7', dataIndex: 'c', key: 'g', width: 150 }, | ||||
|   { title: 'title8', dataIndex: 'c', key: 'h', width: 150 }, | ||||
|   { title: 'title9', dataIndex: 'b', key: 'i', width: 150 }, | ||||
|   { title: 'title10', dataIndex: 'b', key: 'j', width: 150 }, | ||||
|   { title: 'title11', dataIndex: 'b', key: 'k', width: 150 }, | ||||
|   { title: 'title12', dataIndex: 'b', key: 'l', width: 100, fixed: 'right' }, | ||||
| ]; | ||||
| 
 | ||||
| const data = [ | ||||
|   { a: 'aaa', b: 'bbb', c: '内容内容内容内容内容', d: 3, key: '1' }, | ||||
|   { a: 'aaa', b: 'bbb', c: '内容内容内容内容内容', d: 3, key: '2' }, | ||||
|   { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '3' }, | ||||
|   { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '4' }, | ||||
|   { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '5' }, | ||||
|   { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '6' }, | ||||
|   { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '7' }, | ||||
|   { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '8' }, | ||||
|   { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '9' }, | ||||
| ]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>Fixed columns and header</h2> | ||||
|     <Table columns={columns} scroll={{ x: 1650, y: 300 }} data={data} style={{ width: 800 }} /> | ||||
|   </div> | ||||
| , document.getElementById('__react-content')); | ||||
|  | @ -1,39 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: 'title1', dataIndex: 'a', key: 'a', width: 100, fixed: 'left' }, | ||||
|   { title: 'title2', dataIndex: 'b', key: 'b', width: 100, fixed: 'left' }, | ||||
|   { title: 'titletitle3', dataIndex: 'c', key: 'c' }, | ||||
|   { title: 'title4', dataIndex: 'c', key: 'd', width: 150 }, | ||||
|   { title: 'title5', dataIndex: 'c', key: 'e', width: 150 }, | ||||
|   { title: 'title6', dataIndex: 'c', key: 'f', width: 150 }, | ||||
|   { title: 'title7', dataIndex: 'c', key: 'g', width: 150 }, | ||||
|   { title: 'title8', dataIndex: 'c', key: 'h', width: 150 }, | ||||
|   { title: 'title9', dataIndex: 'b', key: 'i', width: 150 }, | ||||
|   { title: 'title10', dataIndex: 'b', key: 'j', width: 150 }, | ||||
|   { title: 'title11', dataIndex: 'b', key: 'k', width: 150 }, | ||||
|   { title: 'title12', dataIndex: 'b', key: 'l', width: 100, fixed: 'right' }, | ||||
| ]; | ||||
| 
 | ||||
| const data = [ | ||||
|   { a: 'aaa', b: 'bbb', c: '内容内容内容内容内容', d: 3, key: '1' }, | ||||
|   { a: 'aaa', b: 'bbb', c: '内容内容内容内容内容', d: 3, key: '2' }, | ||||
|   { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '3' }, | ||||
|   { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '4' }, | ||||
|   { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '5' }, | ||||
|   { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '6' }, | ||||
|   { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '7' }, | ||||
|   { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '8' }, | ||||
|   { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '9' }, | ||||
| ]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>Fixed columns and header, resize window for test</h2> | ||||
|     <Table columns={columns} scroll={{ x: '150%', y: 300 }} data={data} /> | ||||
|   </div> | ||||
| , document.getElementById('__react-content')); | ||||
|  | @ -1,45 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: 'title1', dataIndex: 'a', key: 'a', width: 100, fixed: 'left' }, | ||||
|   { title: 'title2', dataIndex: 'b', key: 'b', width: 100, fixed: 'left' }, | ||||
|   { title: 'title3', dataIndex: 'c', key: 'c' }, | ||||
|   { title: 'title4', dataIndex: 'b', key: 'd' }, | ||||
|   { title: 'title5', dataIndex: 'b', key: 'e' }, | ||||
|   { title: 'title6', dataIndex: 'b', key: 'f' }, | ||||
|   { title: <div>title7<br /><br /><br />Hello world!</div>, dataIndex: 'b', key: 'g' }, | ||||
|   { title: 'title8', dataIndex: 'b', key: 'h' }, | ||||
|   { title: 'title9', dataIndex: 'b', key: 'i' }, | ||||
|   { title: 'title10', dataIndex: 'b', key: 'j' }, | ||||
|   { title: 'title11', dataIndex: 'b', key: 'k' }, | ||||
|   { title: 'title12', dataIndex: 'b', key: 'l', width: 100, fixed: 'right' }, | ||||
| ]; | ||||
| 
 | ||||
| const data = [ | ||||
|   { a: '123', b: 'xxxxxxxx', d: 3, key: '1' }, | ||||
|   { a: 'cdd', b: 'edd12221', d: 3, key: '2' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '3' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '4' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '5' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '6' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '7' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '8' }, | ||||
|   { a: '133', c: 'edd12221', d: 2, key: '9' }, | ||||
| ]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>See fixed columns when you resize window</h2> | ||||
|     <Table | ||||
|       columns={columns} | ||||
|       expandedRowRender={record => record.title} | ||||
|       expandIconAsCell | ||||
|       scroll={{ x: 800 }} | ||||
|       data={data} | ||||
|     /> | ||||
|   </div> | ||||
| , document.getElementById('__react-content')); | ||||
|  | @ -1,100 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| import 'rc-table/assets/bordered.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { | ||||
|     title: '姓名', | ||||
|     dataIndex: 'name', | ||||
|     key: 'name', | ||||
|   }, | ||||
|   { | ||||
|     title: '其它', | ||||
|     children: [ | ||||
|       { | ||||
|         title: '年龄', | ||||
|         dataIndex: 'age', | ||||
|         key: 'age', | ||||
|       }, | ||||
|       { | ||||
|         title: '住址', | ||||
|         children: [ | ||||
|           { | ||||
|             title: '街道', | ||||
|             dataIndex: 'street', | ||||
|             key: 'street', | ||||
|           }, | ||||
|           { | ||||
|             title: '小区', | ||||
|             children: [ | ||||
|               { | ||||
|                 title: '单元', | ||||
|                 dataIndex: 'building', | ||||
|                 key: 'building', | ||||
|               }, | ||||
|               { | ||||
|                 title: '门牌', | ||||
|                 dataIndex: 'number', | ||||
|                 key: 'number', | ||||
|               }, | ||||
|             ], | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|     ], | ||||
|   }, | ||||
|   { | ||||
|     title: '公司', | ||||
|     children: [ | ||||
|       { | ||||
|         title: '地址', | ||||
|         dataIndex: 'companyAddress', | ||||
|         key: 'companyAddress', | ||||
|       }, | ||||
|       { | ||||
|         title: '名称', | ||||
|         dataIndex: 'companyName', | ||||
|         key: 'companyName', | ||||
|       }, | ||||
|     ], | ||||
|   }, | ||||
|   { | ||||
|     title: '性别', | ||||
|     dataIndex: 'gender', | ||||
|     key: 'gender', | ||||
|   }, | ||||
| ]; | ||||
| 
 | ||||
| 
 | ||||
| const data = [{ | ||||
|   key: '1', | ||||
|   name: '胡彦斌', | ||||
|   age: 32, | ||||
|   street: '拱墅区和睦街道', | ||||
|   building: 1, | ||||
|   number: 2033, | ||||
|   companyAddress: '西湖区湖底公园', | ||||
|   companyName: '湖底有限公司', | ||||
|   gender: '男', | ||||
| }, { | ||||
|   key: '2', | ||||
|   name: '胡彦祖', | ||||
|   age: 42, | ||||
|   street: '拱墅区和睦街道', | ||||
|   building: 3, | ||||
|   number: 2035, | ||||
|   companyAddress: '西湖区湖底公园', | ||||
|   companyName: '湖底有限公司', | ||||
|   gender: '男', | ||||
| }]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>grouping columns</h2> | ||||
|     <Table columns={columns} data={data} className="bordered" /> | ||||
|   </div>, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,34 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: 'title1', dataIndex: 'a', key: 'a', width: 100 }, | ||||
|   { id: '123', title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, | ||||
|   { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, | ||||
|   { | ||||
|     title: 'Operations', dataIndex: '', key: 'd', render() { | ||||
|       return <a href="#">Operations</a>; | ||||
|     }, | ||||
|   }, | ||||
| ]; | ||||
| 
 | ||||
| const data = [ | ||||
|   { a: '123', key: '1' }, | ||||
|   { a: 'cdd', b: 'edd', key: '2' }, | ||||
|   { a: '1333', c: 'eee', d: 2, key: '3' }, | ||||
| ]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>hide table head</h2> | ||||
|     <Table | ||||
|       columns={columns} | ||||
|       showHeader={false} | ||||
|       data={data} | ||||
|     /> | ||||
|   </div>, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,49 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const { ColumnGroup, Column } = Table; | ||||
| 
 | ||||
| const data = [ | ||||
|   { a: '123', key: '1' }, | ||||
|   { a: 'cdd', b: 'edd', key: '2' }, | ||||
|   { a: '1333', c: 'eee', d: 2, key: '3' }, | ||||
| ]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>JSX table</h2> | ||||
|     <Table data={data}> | ||||
|       <ColumnGroup title="Bazinga"> | ||||
|         <Column | ||||
|           title="title1" | ||||
|           dataIndex="a" | ||||
|           key="a" | ||||
|           width={100} | ||||
|         /> | ||||
|         <Column | ||||
|           id="123" | ||||
|           title="title2" | ||||
|           dataIndex="b" | ||||
|           key="b" | ||||
|           width={100} | ||||
|         /> | ||||
|       </ColumnGroup> | ||||
|       <Column | ||||
|         title="title3" | ||||
|         dataIndex="c" | ||||
|         key="c" | ||||
|         width={200} | ||||
|       /> | ||||
|       <Column | ||||
|         title="Operations" | ||||
|         dataIndex="" | ||||
|         key="d" | ||||
|         render={() => <a href="#">Operations</a>} | ||||
|       /> | ||||
|     </Table> | ||||
|   </div>, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,70 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const CheckBox = ({ id }) => ( | ||||
|   <label> | ||||
|     <input type="checkbox" /> | ||||
|     {id} | ||||
|   </label> | ||||
| ); | ||||
| 
 | ||||
| class Demo extends React.Component { | ||||
|   static propTypes = { | ||||
|     data: PropTypes.array.isRequired, | ||||
|   } | ||||
| 
 | ||||
|   constructor(props) { | ||||
|     super(props); | ||||
| 
 | ||||
|     this.state = { | ||||
|       data: props.data, | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   remove(index) { | ||||
|     const rows = this.state.data; | ||||
|     rows.splice(index, 1); | ||||
|     this.setState({ | ||||
|       data: rows, | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   handleClick = (index) => () => { | ||||
|     this.remove(index); | ||||
|   } | ||||
| 
 | ||||
|   checkbox(a) { | ||||
|     return <CheckBox id={a} />; | ||||
|   } | ||||
| 
 | ||||
|   renderAction = (o, row, index) => { | ||||
|     return <a href="#" onClick={this.handleClick(index)}>Delete</a>; | ||||
|   } | ||||
| 
 | ||||
|   render() { | ||||
|     const state = this.state; | ||||
|     const columns = [ | ||||
|       { title: 'title1', dataIndex: 'a', key: 'a', width: 100, render: this.checkbox }, | ||||
|       { title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, | ||||
|       { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, | ||||
|       { title: 'Operations', dataIndex: '', key: 'x', render: this.renderAction }, | ||||
|     ]; | ||||
|     return ( | ||||
|       <Table columns={columns} data={state.data} className="table" rowKey={record => record.a} /> | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const data = [{ a: '123' }, { a: 'cdd', b: 'edd' }, { a: '1333', c: 'eee', d: 2 }]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>specify key</h2> | ||||
|     <Demo data={data} /> | ||||
|   </div>, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,45 +0,0 @@ | |||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: 'First Name', dataIndex: 'names.first', key: 'a', width: 100 }, | ||||
|   { title: 'Last Name', dataIndex: 'names.last', key: 'b', width: 100 }, | ||||
|   { title: 'Age', dataIndex: 'age', key: 'c', width: 100 }, | ||||
| ]; | ||||
| 
 | ||||
| const data = [{ | ||||
|   age: '23', | ||||
|   names: { | ||||
|     first: 'John', | ||||
|     last: 'Doe', | ||||
|   }, | ||||
|   key: '1', | ||||
| }, { | ||||
|   age: '36', | ||||
|   names: { | ||||
|     first: 'Terry', | ||||
|     last: 'Garner', | ||||
|   }, | ||||
|   key: '2', | ||||
| }, { | ||||
|   age: '52', | ||||
|   names: { | ||||
|     first: 'Thomas', | ||||
|     last: 'Goodwin', | ||||
|   }, | ||||
|   key: '3', | ||||
| }]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>Nested data table</h2> | ||||
|     <Table | ||||
|       columns={columns} | ||||
|       data={data} | ||||
|       className="table" | ||||
|     /> | ||||
|   </div>, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,26 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: 'title1', dataIndex: 'a', key: 'a', width: 100 }, | ||||
|   { id: '123', title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, | ||||
|   { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, | ||||
|   { | ||||
|     title: 'Operations', dataIndex: '', key: 'd', render() { | ||||
|       return <a href="#">Operations</a>; | ||||
|     }, | ||||
|   }, | ||||
| ]; | ||||
| 
 | ||||
| const data = []; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>simple table</h2> | ||||
|     <Table columns={columns} data={data} /> | ||||
|   </div>, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,187 +0,0 @@ | |||
| /* eslint-disable no-unused-expressions,new-cap */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import { injectGlobal } from 'styled-components'; | ||||
| import update from 'immutability-helper'; | ||||
| import { DragDropContext, DragSource, DropTarget } from 'react-dnd'; | ||||
| import HTML5Backend from 'react-dnd-html5-backend'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| injectGlobal` | ||||
|   tr.drop-over-downward td { | ||||
|     border-bottom: 2px dashed red; | ||||
|   } | ||||
| 
 | ||||
|   tr.drop-over-upward td { | ||||
|     border-top: 2px dashed red; | ||||
|   } | ||||
| `;
 | ||||
| 
 | ||||
| function dragDirection( | ||||
|   dragIndex, | ||||
|   hoverIndex, | ||||
|   initialClientOffset, | ||||
|   clientOffset, | ||||
|   sourceClientOffset, | ||||
| ) { | ||||
|   const hoverMiddleY = (initialClientOffset.y - sourceClientOffset.y) / 2; | ||||
|   const hoverClientY = clientOffset.y - sourceClientOffset.y; | ||||
|   if (dragIndex < hoverIndex && hoverClientY > hoverMiddleY) { | ||||
|     return 'downward'; | ||||
|   } | ||||
|   if (dragIndex > hoverIndex && hoverClientY < hoverMiddleY) { | ||||
|     return 'upward'; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| let BodyRow = (props) => { | ||||
|   const { | ||||
|     isOver, | ||||
|     connectDragSource, | ||||
|     connectDropTarget, | ||||
|     moveRow, | ||||
|     dragRow, | ||||
|     clientOffset, | ||||
|     sourceClientOffset, | ||||
|     initialClientOffset, | ||||
|     ...restProps, | ||||
|   } = props; | ||||
|   const style = { cursor: 'move' }; | ||||
| 
 | ||||
|   let className = restProps.className; | ||||
|   if (isOver && initialClientOffset) { | ||||
|     const direction = dragDirection( | ||||
|       dragRow.index, | ||||
|       restProps.index, | ||||
|       initialClientOffset, | ||||
|       clientOffset, | ||||
|       sourceClientOffset | ||||
|     ); | ||||
|     if (direction === 'downward') { | ||||
|       className += ' drop-over-downward'; | ||||
|     } | ||||
|     if (direction === 'upward') { | ||||
|       className += ' drop-over-upward'; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return connectDragSource( | ||||
|     connectDropTarget( | ||||
|       <tr | ||||
|         {...restProps} | ||||
|         className={className} | ||||
|         style={style} | ||||
|       /> | ||||
|     ) | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| const rowSource = { | ||||
|   beginDrag(props) { | ||||
|     return { | ||||
|       index: props.index, | ||||
|     }; | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| const rowTarget = { | ||||
|   drop(props, monitor) { | ||||
|     const dragIndex = monitor.getItem().index; | ||||
|     const hoverIndex = props.index; | ||||
| 
 | ||||
|     // Don't replace items with themselves
 | ||||
|     if (dragIndex === hoverIndex) { | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     // Time to actually perform the action
 | ||||
|     props.moveRow(dragIndex, hoverIndex); | ||||
| 
 | ||||
|     // Note: we're mutating the monitor item here!
 | ||||
|     // Generally it's better to avoid mutations,
 | ||||
|     // but it's good here for the sake of performance
 | ||||
|     // to avoid expensive index searches.
 | ||||
|     monitor.getItem().index = hoverIndex; | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| BodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({ | ||||
|   connectDropTarget: connect.dropTarget(), | ||||
|   isOver: monitor.isOver(), | ||||
|   sourceClientOffset: monitor.getSourceClientOffset(), | ||||
| }))( | ||||
|   DragSource('row', rowSource, (connect, monitor) => ({ | ||||
|     connectDragSource: connect.dragSource(), | ||||
|     dragRow: monitor.getItem(), | ||||
|     clientOffset: monitor.getClientOffset(), | ||||
|     initialClientOffset: monitor.getInitialClientOffset(), | ||||
|   }))(BodyRow) | ||||
| ); | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: 'title1', dataIndex: 'a', key: 'a', width: 100 }, | ||||
|   { id: '123', title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, | ||||
|   { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, | ||||
|   { | ||||
|     title: 'Operations', | ||||
|     dataIndex: '', | ||||
|     key: 'd', | ||||
|     render() { | ||||
|       return <a href="#">Operations</a>; | ||||
|     }, | ||||
|   }, | ||||
| ]; | ||||
| 
 | ||||
| class Demo extends React.Component { | ||||
|   state = { | ||||
|     data: [ | ||||
|       { a: '123', key: '1' }, | ||||
|       { a: 'cdd', b: 'edd', key: '2' }, | ||||
|       { a: '1333', c: 'eee', d: 2, key: '3' }, | ||||
|     ], | ||||
|   } | ||||
| 
 | ||||
|   components = { | ||||
|     body: { | ||||
|       row: BodyRow, | ||||
|     }, | ||||
|   } | ||||
| 
 | ||||
|   moveRow = (dragIndex, hoverIndex) => { | ||||
|     const { data } = this.state; | ||||
|     const dragRow = data[dragIndex]; | ||||
| 
 | ||||
|     this.setState( | ||||
|       update(this.state, { | ||||
|         data: { | ||||
|           $splice: [[dragIndex, 1], [hoverIndex, 0, dragRow]], | ||||
|         }, | ||||
|       }), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   render() { | ||||
|     return ( | ||||
|       <Table | ||||
|         columns={columns} | ||||
|         data={this.state.data} | ||||
|         components={this.components} | ||||
|         onRow={(record, index) => ({ | ||||
|           index, | ||||
|           moveRow: this.moveRow, | ||||
|         })} | ||||
|       /> | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| Demo = DragDropContext(HTML5Backend)(Demo); | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>Integrate with react-dnd</h2> | ||||
|     <Demo /> | ||||
|   </div>, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,105 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const onRowClick = (record, index, event) => { | ||||
|   console.log(`Click nth(${index}) row of parent, record.name: ${record.name}`); | ||||
|   // See https://facebook.github.io/react/docs/events.html for original click event details.
 | ||||
|   if (event.shiftKey) { | ||||
|     console.log('Shift + mouse click triggered.'); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| const onRowDoubleClick = (record, index) => { | ||||
|   console.log(`Double click nth(${index}) row of parent, record.name: ${record.name}`); | ||||
| }; | ||||
| 
 | ||||
| const columns = [{ | ||||
|   title: 'Name', | ||||
|   dataIndex: 'name', | ||||
|   key: 'name', | ||||
|   width: 400, | ||||
| }, { | ||||
|   title: 'Age', | ||||
|   dataIndex: 'age', | ||||
|   key: 'age', | ||||
|   width: 100, | ||||
|   render: (text) => ( | ||||
|     <span>{text} (Trigger Cell Click)</span> | ||||
|   ), | ||||
|   onCell: (record) => ({ | ||||
|     onClick(e) { | ||||
|       console.log('Click cell', record, e.target); | ||||
|     }, | ||||
|   }), | ||||
| }, { | ||||
|   title: 'Address', | ||||
|   dataIndex: 'address', | ||||
|   key: 'address', | ||||
|   width: 200, | ||||
| }]; | ||||
| 
 | ||||
| const data = [{ | ||||
|   key: 1, | ||||
|   name: 'a', | ||||
|   age: 32, | ||||
|   address: 'I am a', | ||||
|   children: [{ | ||||
|     key: 11, | ||||
|     name: 'aa', | ||||
|     age: 33, | ||||
|     address: 'I am aa', | ||||
|   }, { | ||||
|     key: 12, | ||||
|     name: 'ab', | ||||
|     age: 33, | ||||
|     address: 'I am ab', | ||||
|     children: [{ | ||||
|       key: 121, | ||||
|       name: 'aba', | ||||
|       age: 33, | ||||
|       address: 'I am aba', | ||||
|     }], | ||||
|   }, { | ||||
|     key: 13, | ||||
|     name: 'ac', | ||||
|     age: 33, | ||||
|     address: 'I am ac', | ||||
|     children: [{ | ||||
|       key: 131, | ||||
|       name: 'aca', | ||||
|       age: 33, | ||||
|       address: 'I am aca', | ||||
|       children: [{ | ||||
|         key: 1311, | ||||
|         name: 'acaa', | ||||
|         age: 33, | ||||
|         address: 'I am acaa', | ||||
|       }, { | ||||
|         key: 1312, | ||||
|         name: 'acab', | ||||
|         age: 33, | ||||
|         address: 'I am acab', | ||||
|       }], | ||||
|     }], | ||||
|   }], | ||||
| }, { | ||||
|   key: 2, | ||||
|   name: 'b', | ||||
|   age: 32, | ||||
|   address: 'I am b', | ||||
| }]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <Table | ||||
|     columns={columns} | ||||
|     data={data} | ||||
|     onRow={(record, index) => ({ | ||||
|       onClick: onRowClick.bind(null, record, index), | ||||
|       onDoubleClick: onRowDoubleClick.bind(null, record, index), | ||||
|     })} | ||||
|   />, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,34 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: 'title1', dataIndex: 'a', key: 'a', width: 100 }, | ||||
|   { title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, | ||||
|   { title: 'title3', dataIndex: 'c', key: 'c', width: 100 }, | ||||
|   { title: 'title4', dataIndex: 'b', key: 'd', width: 100 }, | ||||
|   { title: 'title5', dataIndex: 'b', key: 'e', width: 100 }, | ||||
|   { title: 'title6', dataIndex: 'b', key: 'f', width: 100 }, | ||||
|   { title: 'title7', dataIndex: 'b', key: 'g', width: 100 }, | ||||
|   { title: 'title8', dataIndex: 'b', key: 'h', width: 100 }, | ||||
|   { title: 'title9', dataIndex: 'b', key: 'i', width: 100 }, | ||||
|   { title: 'title10', dataIndex: 'b', key: 'j', width: 100 }, | ||||
|   { title: 'title11', dataIndex: 'b', key: 'k', width: 100 }, | ||||
|   { title: 'title12', dataIndex: 'b', key: 'l', width: 100 }, | ||||
| ]; | ||||
| 
 | ||||
| const data = [ | ||||
|   { a: '123', b: 'xxxxxxxx xxxxxxxx', d: 3, key: '1' }, | ||||
|   { a: 'cdd', b: 'edd12221 edd12221', d: 3, key: '2' }, | ||||
|   { a: '133', c: 'edd12221 edd12221', d: 2, key: '3' }, | ||||
|   { a: '133', c: 'edd12221 edd12221', d: 2, key: '4' }, | ||||
| ]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>Scroll X</h2> | ||||
|     <Table style={{ width: 800 }} scroll={{ x: true }} columns={columns} data={data} /> | ||||
|   </div> | ||||
| , document.getElementById('__react-content')); | ||||
|  | @ -1,45 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: 'title1', dataIndex: 'a', key: 'a', width: 100 }, | ||||
|   { title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, | ||||
|   { title: 'title3', dataIndex: 'c', key: 'c', width: 100 }, | ||||
|   { title: 'title4', dataIndex: 'b', key: 'd', width: 100 }, | ||||
|   { title: 'title5', dataIndex: 'b', key: 'e', width: 100 }, | ||||
|   { title: 'title6', dataIndex: 'b', key: 'f', width: 100 }, | ||||
|   { title: 'title7', dataIndex: 'b', key: 'g', width: 100 }, | ||||
|   { title: 'title8', dataIndex: 'b', key: 'h', width: 100 }, | ||||
|   { title: 'title9', dataIndex: 'b', key: 'i', width: 100 }, | ||||
|   { title: 'title10', dataIndex: 'b', key: 'j', width: 100 }, | ||||
|   { title: 'title11', dataIndex: 'b', key: 'k', width: 100 }, | ||||
|   { title: 'title12', dataIndex: 'b', key: 'l', width: 100 }, | ||||
| ]; | ||||
| 
 | ||||
| const data = [ | ||||
|   { a: '123', b: 'xxxxxxxx xxxxxxxx', d: 3, key: '1' }, | ||||
|   { a: 'cdd', b: 'edd12221 edd12221', d: 3, key: '2' }, | ||||
|   { a: '133', c: 'edd12221 edd12221', d: 2, key: '3' }, | ||||
|   { a: '133', c: 'edd12221 edd12221', d: 2, key: '4' }, | ||||
|   { a: '133', c: 'edd12221 edd12221', d: 2, key: '5' }, | ||||
|   { a: '133', c: 'edd12221 edd12221', d: 2, key: '6' }, | ||||
|   { a: '133', c: 'edd12221 edd12221', d: 2, key: '7' }, | ||||
|   { a: '133', c: 'edd12221 edd12221', d: 2, key: '8' }, | ||||
|   { a: '133', c: 'edd12221 edd12221', d: 2, key: '9' }, | ||||
| ]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>Scroll X/Y</h2> | ||||
|     <Table | ||||
|       useFixedHeader | ||||
|       style={{ width: 800 }} | ||||
|       scroll={{ x: 1500, y: 300 }} | ||||
|       columns={columns} | ||||
|       data={data} | ||||
|     /> | ||||
|   </div> | ||||
| , document.getElementById('__react-content')); | ||||
|  | @ -1,62 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const data = []; | ||||
| for (let i = 0; i < 10; i++) { | ||||
|   data.push({ | ||||
|     key: i, | ||||
|     a: `a${i}`, | ||||
|     b: `b${i}`, | ||||
|     c: `c${i}`, | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| class Demo extends React.Component { | ||||
|   state = { | ||||
|     showBody: true, | ||||
|   } | ||||
| 
 | ||||
|   toggleBody = () => { | ||||
|     this.setState({ | ||||
|       showBody: !this.state.showBody, | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   render() { | ||||
|     const columns = [ | ||||
|       { title: 'title1', key: 'a', dataIndex: 'a', width: 100 }, | ||||
|       { id: '123', title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, | ||||
|       { title: 'title3', key: 'c', dataIndex: 'c', width: 200 }, | ||||
|       { | ||||
|         title: <a onClick={this.toggleBody} href="#">{this.state.showBody ? '隐藏' : '显示'}体</a>, | ||||
|         key: 'x', | ||||
|         width: 200, | ||||
|         render() { | ||||
|           return <a href="#">Operations</a>; | ||||
|         }, | ||||
|       }, | ||||
|     ]; | ||||
|     return ( | ||||
|       <Table | ||||
|         columns={columns} | ||||
|         data={data} | ||||
|         scroll={{ y: 300 }} | ||||
|         rowKey={record => record.key} | ||||
|         bodyStyle={{ | ||||
|           display: this.state.showBody ? '' : 'none', | ||||
|         }} | ||||
|       /> | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>scroll body table</h2> | ||||
|     <Demo /> | ||||
|   </div>, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,30 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: 'title1', dataIndex: 'a', key: 'a', width: 100 }, | ||||
|   { id: '123', title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, | ||||
|   { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, | ||||
|   { | ||||
|     title: 'Operations', dataIndex: '', key: 'd', render() { | ||||
|       return <a href="#">Operations</a>; | ||||
|     }, | ||||
|   }, | ||||
| ]; | ||||
| 
 | ||||
| const data = [ | ||||
|   { a: '123', key: '1' }, | ||||
|   { a: 'cdd', b: 'edd', key: '2' }, | ||||
|   { a: '1333', c: 'eee', d: 2, key: '3' }, | ||||
| ]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>simple table</h2> | ||||
|     <Table columns={columns} data={data} /> | ||||
|   </div>, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,45 +0,0 @@ | |||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import styled from 'styled-components'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: 'title1', dataIndex: 'a', key: 'a', width: 100 }, | ||||
|   { id: '123', title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, | ||||
|   { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, | ||||
|   { | ||||
|     title: 'Operations', | ||||
|     dataIndex: '', | ||||
|     key: 'd', | ||||
|     render() { | ||||
|       return <a href="#">Operations</a>; | ||||
|     }, | ||||
|   }, | ||||
| ]; | ||||
| 
 | ||||
| const data = [ | ||||
|   { a: '123', key: '1' }, | ||||
|   { a: 'cdd', b: 'edd', key: '2' }, | ||||
|   { a: '1333', c: 'eee', d: 2, key: '3' }, | ||||
| ]; | ||||
| 
 | ||||
| const BodyRow = styled.tr` | ||||
| 	&:hover { | ||||
| 		background: palevioletred !important; | ||||
| 	} | ||||
| `;
 | ||||
| 
 | ||||
| const components = { | ||||
|   body: { | ||||
|     row: BodyRow, | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>Integrate with styled-components</h2> | ||||
|     <Table columns={columns} data={data} components={components} /> | ||||
|   </div>, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -1,63 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const data = [ | ||||
|   { | ||||
|     a: 'a1', | ||||
|   }, | ||||
|   { | ||||
|     a: 'a2', | ||||
|     b: 'b2', | ||||
|     children: [ | ||||
|       { | ||||
|         a: 'a2-1', | ||||
|         b: 'b2-1', | ||||
|       }, | ||||
|       { | ||||
|         a: 'a2-2', | ||||
|         b: 'b2-2', | ||||
|       }, | ||||
|     ], | ||||
|   }, | ||||
|   { | ||||
|     a: 'a3', | ||||
|     c: 'c3', | ||||
|     d: 'd3', | ||||
|   }, | ||||
| ]; | ||||
| 
 | ||||
| class Demo extends React.Component { | ||||
|   handleClick = (record, e) => { | ||||
|     e.preventDefault(); | ||||
|     console.log(record.a); | ||||
|   } | ||||
| 
 | ||||
|   render() { | ||||
|     const columns = [ | ||||
|       { title: 'title1', dataIndex: 'a', key: 'a', width: 100 }, | ||||
|       { title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, | ||||
|       { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, | ||||
|       { | ||||
|         title: 'Operations', dataIndex: '', key: 'x', render: (text, record) => { | ||||
|           return <a href="#" onClick={e => this.handleClick(record, e)}>click {record.a}</a>; | ||||
|         }, | ||||
|       }, | ||||
|     ]; | ||||
|     return ( | ||||
|       <div> | ||||
|         <h2>sub table</h2> | ||||
|         <Table | ||||
|           columns={columns} | ||||
|           expandIconAsCell | ||||
|           data={data} | ||||
|           rowKey={record => record.a} | ||||
|         /> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| ReactDOM.render(<Demo />, document.getElementById('__react-content')); | ||||
|  | @ -1,35 +0,0 @@ | |||
| /* eslint-disable no-console,func-names,react/no-multi-comp */ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import Table from 'rc-table'; | ||||
| import 'rc-table/assets/index.less'; | ||||
| 
 | ||||
| const columns = [ | ||||
|   { title: 'title1', dataIndex: 'a', key: 'a', width: 100 }, | ||||
|   { id: '123', title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, | ||||
|   { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, | ||||
|   { | ||||
|     title: 'Operations', dataIndex: '', key: 'd', render() { | ||||
|       return <a href="#">Operations</a>; | ||||
|     }, | ||||
|   }, | ||||
| ]; | ||||
| 
 | ||||
| const data = [ | ||||
|   { a: '123', key: '1' }, | ||||
|   { a: 'cdd', b: 'edd', key: '2' }, | ||||
|   { a: '1333', c: 'eee', d: 2, key: '3' }, | ||||
| ]; | ||||
| 
 | ||||
| ReactDOM.render( | ||||
|   <div> | ||||
|     <h2>title and footer</h2> | ||||
|     <Table | ||||
|       columns={columns} | ||||
|       data={data} | ||||
|       title={currentData => <div>Title: {currentData.length} items</div>} | ||||
|       footer={currentData => <div>Footer: {currentData.length} items</div>} | ||||
|     /> | ||||
|   </div>, | ||||
|   document.getElementById('__react-content') | ||||
| ); | ||||
|  | @ -5,7 +5,8 @@ import TableHeader from './TableHeader' | |||
| import TableRow from './TableRow' | ||||
| import ExpandableRow from './ExpandableRow' | ||||
| import { mergeProps } from '../../_util/props-util' | ||||
| 
 | ||||
| import { connect } from '../../_util/store' | ||||
| function noop () {} | ||||
| const BaseTable = { | ||||
|   name: 'BaseTable', | ||||
|   props: { | ||||
|  | @ -34,18 +35,18 @@ const BaseTable = { | |||
| 
 | ||||
|     renderRows  (renderData, indent, ancestorKeys = []) { | ||||
|       const { | ||||
|         columnManager, components, | ||||
|         columnManager, sComponents: components, | ||||
|         prefixCls, | ||||
|         childrenColumnName, | ||||
|         rowClassName, | ||||
|         // rowRef, | ||||
|         $listeners: { | ||||
|           rowClick: onRowClick, | ||||
|           rowDoubleclick: onRowDoubleClick, | ||||
|           rowContextmenu: onRowContextMenu, | ||||
|           rowMouseenter: onRowMouseEnter, | ||||
|           rowMouseleave: onRowMouseLeave, | ||||
|           row: onRow, | ||||
|           rowClick: onRowClick = noop, | ||||
|           rowDoubleclick: onRowDoubleClick = noop, | ||||
|           rowContextmenu: onRowContextMenu = noop, | ||||
|           rowMouseenter: onRowMouseEnter = noop, | ||||
|           rowMouseleave: onRowMouseLeave = noop, | ||||
|           row: onRow = noop, | ||||
|         }, | ||||
|       } = this.table | ||||
|       const { getRowKey, fixed, expander, isAnyColumnsFixed } = this | ||||
|  | @ -86,6 +87,7 @@ const BaseTable = { | |||
|           }, | ||||
|           key, | ||||
|           on: { | ||||
|             // ...expander.on, | ||||
|             rowClick: onRowClick, | ||||
|             expandedChange: expander.handleExpandChange, | ||||
|           }, | ||||
|  | @ -148,7 +150,7 @@ const BaseTable = { | |||
|   }, | ||||
| 
 | ||||
|   render () { | ||||
|     const { components, prefixCls, scroll, data, getBodyWrapper } = this.table | ||||
|     const { sComponents: components, prefixCls, scroll, data, getBodyWrapper } = this.table | ||||
|     const { expander, tableClassName, hasHead, hasBody, fixed, columns } = this | ||||
|     const tableStyle = {} | ||||
| 
 | ||||
|  | @ -186,4 +188,4 @@ const BaseTable = { | |||
|   }, | ||||
| } | ||||
| 
 | ||||
| export default BaseTable | ||||
| export default connect()(BaseTable) | ||||
|  |  | |||
|  | @ -4,13 +4,14 @@ export default { | |||
|   name: 'ColGroup', | ||||
|   props: { | ||||
|     fixed: PropTypes.string, | ||||
|     columns: PropTypes.array, | ||||
|   }, | ||||
|   inject: { | ||||
|     table: { default: {}}, | ||||
|   }, | ||||
|   render () { | ||||
|     const { fixed, table } = this | ||||
|     const { prefixCls, expandIconAsCell } = table | ||||
|     const { prefixCls, expandIconAsCell, columnManager } = table | ||||
| 
 | ||||
|     let cols = [] | ||||
| 
 | ||||
|  | @ -26,18 +27,19 @@ export default { | |||
|     let leafColumns | ||||
| 
 | ||||
|     if (fixed === 'left') { | ||||
|       leafColumns = table.columnManager.leftLeafColumns() | ||||
|       leafColumns = columnManager.leftLeafColumns() | ||||
|     } else if (fixed === 'right') { | ||||
|       leafColumns = table.columnManager.rightLeafColumns() | ||||
|       leafColumns = columnManager.rightLeafColumns() | ||||
|     } else { | ||||
|       leafColumns = table.columnManager.leafColumns() | ||||
|       leafColumns = columnManager.leafColumns() | ||||
|     } | ||||
|     cols = cols.concat( | ||||
|       leafColumns.map(c => { | ||||
|         const width = typeof c.width === 'number' ? `${c.width}px` : c.width | ||||
|         return ( | ||||
|           <col | ||||
|             key={c.key || c.dataIndex} | ||||
|             style={{ width: c.width, minWidth: c.width }} | ||||
|             style={{ width, minWidth: width }} | ||||
|           /> | ||||
|         ) | ||||
|       }) | ||||
|  |  | |||
|  | @ -1,8 +1,7 @@ | |||
| export default class ColumnManager { | ||||
|   _cached = {} | ||||
| 
 | ||||
|   constructor (columns, elements) { | ||||
|     this.columns = columns || this.normalize(elements) | ||||
|     this._cached = {} | ||||
|   } | ||||
| 
 | ||||
|   isAnyColumnsFixed () { | ||||
|  | @ -1,6 +1,7 @@ | |||
| import PropTypes from '../../_util/vue-types' | ||||
| import ExpandIcon from './ExpandIcon' | ||||
| import BaseMixin from '../../_util/BaseMixin' | ||||
| import { connect } from '../../_util/store' | ||||
| 
 | ||||
| const ExpandableRow = { | ||||
|   mixins: [BaseMixin], | ||||
|  | @ -32,61 +33,62 @@ const ExpandableRow = { | |||
|   beforeDestroy () { | ||||
|     this.handleDestroy() | ||||
|   }, | ||||
|   methods: { | ||||
|     hasExpandIcon (columnIndex) { | ||||
|       const { expandRowByClick } = this | ||||
|       return !this.expandIconAsCell && | ||||
|         !expandRowByClick && | ||||
|         columnIndex === this.expandIconColumnIndex | ||||
|     }, | ||||
| 
 | ||||
|   hasExpandIcon (columnIndex) { | ||||
|     const { expandRowByClick } = this | ||||
|     return !this.expandIconAsCell && | ||||
|       !expandRowByClick && | ||||
|       columnIndex === this.expandIconColumnIndex | ||||
|   }, | ||||
|     handleExpandChange (record, event) { | ||||
|       const { expanded, rowKey } = this | ||||
|       this.__emit('expandedChange', !expanded, record, event, rowKey) | ||||
|     }, | ||||
| 
 | ||||
|   handleExpandChange (record, event) { | ||||
|     const { expanded, rowKey } = this | ||||
|     this.__emit('expandedChange', !expanded, record, event, rowKey) | ||||
|   }, | ||||
|     handleDestroy () { | ||||
|       const { rowKey, record } = this | ||||
|       this.__emit('expandedChange', false, record, null, rowKey, true) | ||||
|     }, | ||||
| 
 | ||||
|   handleDestroy () { | ||||
|     const { rowKey, record } = this | ||||
|     this.__emit('expandedChange', false, record, null, rowKey, true) | ||||
|   }, | ||||
|     handleRowClick (record, index, event) { | ||||
|       const { expandRowByClick } = this | ||||
|       if (expandRowByClick) { | ||||
|         this.handleExpandChange(record, event) | ||||
|       } | ||||
|       this.__emit('rowClick', record, index, event) | ||||
|     }, | ||||
| 
 | ||||
|   handleRowClick (record, index, event) { | ||||
|     const { expandRowByClick } = this | ||||
|     if (expandRowByClick) { | ||||
|       this.handleExpandChange(record, event) | ||||
|     } | ||||
|     this.__emit('rowClick', record, index, event) | ||||
|   }, | ||||
|     renderExpandIcon () { | ||||
|       const { prefixCls, expanded, record, needIndentSpaced } = this | ||||
| 
 | ||||
|   renderExpandIcon () { | ||||
|     const { prefixCls, expanded, record, needIndentSpaced } = this | ||||
|       return ( | ||||
|         <ExpandIcon | ||||
|           expandable={this.expandable} | ||||
|           prefixCls={prefixCls} | ||||
|           onExpand={this.handleExpandChange} | ||||
|           needIndentSpaced={needIndentSpaced} | ||||
|           expanded={expanded} | ||||
|           record={record} | ||||
|         /> | ||||
|       ) | ||||
|     }, | ||||
| 
 | ||||
|     return ( | ||||
|       <ExpandIcon | ||||
|         expandable={this.expandable} | ||||
|         prefixCls={prefixCls} | ||||
|         onExpand={this.handleExpandChange} | ||||
|         needIndentSpaced={needIndentSpaced} | ||||
|         expanded={expanded} | ||||
|         record={record} | ||||
|       /> | ||||
|     ) | ||||
|   }, | ||||
|     renderExpandIconCell  (cells) { | ||||
|       if (!this.expandIconAsCell) { | ||||
|         return | ||||
|       } | ||||
|       const { prefixCls } = this | ||||
| 
 | ||||
|   renderExpandIconCell  (cells) { | ||||
|     if (!this.expandIconAsCell) { | ||||
|       return | ||||
|     } | ||||
|     const { prefixCls } = this | ||||
| 
 | ||||
|     cells.push( | ||||
|       <td | ||||
|         class={`${prefixCls}-expand-icon-cell`} | ||||
|         key='rc-table-expand-icon-cell' | ||||
|       > | ||||
|         {this.renderExpandIcon()} | ||||
|       </td> | ||||
|     ) | ||||
|       cells.push( | ||||
|         <td | ||||
|           class={`${prefixCls}-expand-icon-cell`} | ||||
|           key='rc-table-expand-icon-cell' | ||||
|         > | ||||
|           {this.renderExpandIcon()} | ||||
|         </td> | ||||
|       ) | ||||
|     }, | ||||
|   }, | ||||
| 
 | ||||
|   render () { | ||||
|  | @ -103,7 +105,6 @@ const ExpandableRow = { | |||
|     this.expandIconColumnIndex = fixed !== 'right' ? this.expandIconColumnIndex : -1 | ||||
|     const childrenData = record[childrenColumnName] | ||||
|     this.expandable = !!(childrenData || expandedRowRender) | ||||
| 
 | ||||
|     const expandableRowProps = { | ||||
|       props: { | ||||
|         indentSize, | ||||
|  | @ -1,223 +0,0 @@ | |||
| import React from 'react' | ||||
| import PropTypes from 'prop-types' | ||||
| import { connect } from 'mini-store' | ||||
| import TableRow from './TableRow' | ||||
| import { remove } from './utils' | ||||
| 
 | ||||
| class ExpandableTable extends React.Component { | ||||
|   static propTypes = { | ||||
|     expandIconAsCell: PropTypes.bool, | ||||
|     expandedRowKeys: PropTypes.array, | ||||
|     expandedRowClassName: PropTypes.func, | ||||
|     defaultExpandAllRows: PropTypes.bool, | ||||
|     defaultExpandedRowKeys: PropTypes.array, | ||||
|     expandIconColumnIndex: PropTypes.number, | ||||
|     expandedRowRender: PropTypes.func, | ||||
|     childrenColumnName: PropTypes.string, | ||||
|     indentSize: PropTypes.number, | ||||
|     onExpand: PropTypes.func, | ||||
|     onExpandedRowsChange: PropTypes.func, | ||||
|     columnManager: PropTypes.object.isRequired, | ||||
|     store: PropTypes.object.isRequired, | ||||
|     prefixCls: PropTypes.string.isRequired, | ||||
|     data: PropTypes.array, | ||||
|     children: PropTypes.func.isRequired, | ||||
|   } | ||||
| 
 | ||||
|   static defaultProps = { | ||||
|     expandIconAsCell: false, | ||||
|     expandedRowClassName: () => '', | ||||
|     expandIconColumnIndex: 0, | ||||
|     defaultExpandAllRows: false, | ||||
|     defaultExpandedRowKeys: [], | ||||
|     childrenColumnName: 'children', | ||||
|     indentSize: 15, | ||||
|     onExpand () {}, | ||||
|     onExpandedRowsChange () {}, | ||||
|   } | ||||
| 
 | ||||
|   constructor (props) { | ||||
|     super(props) | ||||
| 
 | ||||
|     const { | ||||
|       data, | ||||
|       childrenColumnName, | ||||
|       defaultExpandAllRows, | ||||
|       expandedRowKeys, | ||||
|       defaultExpandedRowKeys, | ||||
|       getRowKey, | ||||
|     } = props | ||||
| 
 | ||||
|     let finnalExpandedRowKeys = [] | ||||
|     let rows = [...data] | ||||
| 
 | ||||
|     if (defaultExpandAllRows) { | ||||
|       for (let i = 0; i < rows.length; i++) { | ||||
|         const row = rows[i] | ||||
|         finnalExpandedRowKeys.push(getRowKey(row, i)) | ||||
|         rows = rows.concat(row[childrenColumnName] || []) | ||||
|       } | ||||
|     } else { | ||||
|       finnalExpandedRowKeys = expandedRowKeys || defaultExpandedRowKeys | ||||
|     } | ||||
| 
 | ||||
|     this.columnManager = props.columnManager | ||||
|     this.store = props.store | ||||
| 
 | ||||
|     this.store.setState({ | ||||
|       expandedRowsHeight: {}, | ||||
|       expandedRowKeys: finnalExpandedRowKeys, | ||||
|     }) | ||||
|   } | ||||
| 
 | ||||
|   componentWillReceiveProps (nextProps) { | ||||
|     if ('expandedRowKeys' in nextProps) { | ||||
|       this.store.setState({ | ||||
|         expandedRowKeys: nextProps.expandedRowKeys, | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   handleExpandChange = (expanded, record, event, rowKey, destroy = false) => { | ||||
|     if (event) { | ||||
|       event.preventDefault() | ||||
|       event.stopPropagation() | ||||
|     } | ||||
| 
 | ||||
|     const { onExpandedRowsChange, onExpand } = this.props | ||||
|     let { expandedRowKeys } = this.store.getState() | ||||
| 
 | ||||
|     if (expanded) { | ||||
|       // row was expaned
 | ||||
|       expandedRowKeys = [...expandedRowKeys, rowKey] | ||||
|     } else { | ||||
|       // row was collapse
 | ||||
|       const expandedRowIndex = expandedRowKeys.indexOf(rowKey) | ||||
|       if (expandedRowIndex !== -1) { | ||||
|         expandedRowKeys = remove(expandedRowKeys, rowKey) | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     if (!this.props.expandedRowKeys) { | ||||
|       this.store.setState({ expandedRowKeys }) | ||||
|     } | ||||
| 
 | ||||
|     onExpandedRowsChange(expandedRowKeys) | ||||
|     if (!destroy) { | ||||
|       onExpand(expanded, record) | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   renderExpandIndentCell = (rows, fixed) => { | ||||
|     const { prefixCls, expandIconAsCell } = this.props | ||||
|     if (!expandIconAsCell || fixed === 'right' || !rows.length) { | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     const iconColumn = { | ||||
|       key: 'rc-table-expand-icon-cell', | ||||
|       className: `${prefixCls}-expand-icon-th`, | ||||
|       title: '', | ||||
|       rowSpan: rows.length, | ||||
|     } | ||||
| 
 | ||||
|     rows[0].unshift({ ...iconColumn, column: iconColumn }) | ||||
|   } | ||||
| 
 | ||||
|   renderExpandedRow (record, index, render, className, ancestorKeys, indent, fixed) { | ||||
|     const { prefixCls, expandIconAsCell, indentSize } = this.props | ||||
|     let colCount | ||||
|     if (fixed === 'left') { | ||||
|       colCount = this.columnManager.leftLeafColumns().length | ||||
|     } else if (fixed === 'right') { | ||||
|       colCount = this.columnManager.rightLeafColumns().length | ||||
|     } else { | ||||
|       colCount = this.columnManager.leafColumns().length | ||||
|     } | ||||
|     const columns = [{ | ||||
|       key: 'extra-row', | ||||
|       render: () => ({ | ||||
|         props: { | ||||
|           colSpan: colCount, | ||||
|         }, | ||||
|         children: fixed !== 'right' ? render(record, index, indent) : ' ', | ||||
|       }), | ||||
|     }] | ||||
|     if (expandIconAsCell && fixed !== 'right') { | ||||
|       columns.unshift({ | ||||
|         key: 'expand-icon-placeholder', | ||||
|         render: () => null, | ||||
|       }) | ||||
|     } | ||||
|     const parentKey = ancestorKeys[ancestorKeys.length - 1] | ||||
|     const rowKey = `${parentKey}-extra-row` | ||||
|     const components = { | ||||
|       body: { | ||||
|         row: 'tr', | ||||
|         cell: 'td', | ||||
|       }, | ||||
|     } | ||||
| 
 | ||||
|     return ( | ||||
|       <TableRow | ||||
|         key={rowKey} | ||||
|         columns={columns} | ||||
|         className={className} | ||||
|         rowKey={rowKey} | ||||
|         ancestorKeys={ancestorKeys} | ||||
|         prefixCls={`${prefixCls}-expanded-row`} | ||||
|         indentSize={indentSize} | ||||
|         indent={indent} | ||||
|         fixed={fixed} | ||||
|         components={components} | ||||
|         expandedRow | ||||
|       /> | ||||
|     ) | ||||
|   } | ||||
| 
 | ||||
|   renderRows = (renderRows, rows, record, index, indent, fixed, parentKey, ancestorKeys) => { | ||||
|     const { expandedRowClassName, expandedRowRender, childrenColumnName } = this.props | ||||
|     const childrenData = record[childrenColumnName] | ||||
|     const nextAncestorKeys = [...ancestorKeys, parentKey] | ||||
|     const nextIndent = indent + 1 | ||||
| 
 | ||||
|     if (expandedRowRender) { | ||||
|       rows.push( | ||||
|         this.renderExpandedRow( | ||||
|           record, | ||||
|           index, | ||||
|           expandedRowRender, | ||||
|           expandedRowClassName(record, index, indent), | ||||
|           nextAncestorKeys, | ||||
|           nextIndent, | ||||
|           fixed, | ||||
|         ), | ||||
|       ) | ||||
|     } | ||||
| 
 | ||||
|     if (childrenData) { | ||||
|       rows.push( | ||||
|         ...renderRows( | ||||
|           childrenData, | ||||
|           nextIndent, | ||||
|           nextAncestorKeys, | ||||
|         ) | ||||
|       ) | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   render () { | ||||
|     const { data, childrenColumnName, children } = this.props | ||||
|     const needIndentSpaced = data.some(record => record[childrenColumnName]) | ||||
| 
 | ||||
|     return children({ | ||||
|       props: this.props, | ||||
|       needIndentSpaced, | ||||
|       renderRows: this.renderRows, | ||||
|       handleExpandChange: this.handleExpandChange, | ||||
|       renderExpandIndentCell: this.renderExpandIndentCell, | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export default connect()(ExpandableTable) | ||||
|  | @ -0,0 +1,223 @@ | |||
| import PropTypes from '../../_util/vue-types' | ||||
| import BaseMixin from '../../_util/BaseMixin' | ||||
| import { connect } from '../../_util/store' | ||||
| import TableRow from './TableRow' | ||||
| import { remove } from './utils' | ||||
| import { initDefaultProps, getOptionProps } from '../../_util/props-util' | ||||
| 
 | ||||
| export const ExpandableTableProps = () => ({ | ||||
|   expandIconAsCell: PropTypes.bool, | ||||
|   expandedRowKeys: PropTypes.array, | ||||
|   expandedRowClassName: PropTypes.func, | ||||
|   defaultExpandAllRows: PropTypes.bool, | ||||
|   defaultExpandedRowKeys: PropTypes.array, | ||||
|   expandIconColumnIndex: PropTypes.number, | ||||
|   expandedRowRender: PropTypes.func, | ||||
|   childrenColumnName: PropTypes.string, | ||||
|   indentSize: PropTypes.number, | ||||
|   // onExpand: PropTypes.func, | ||||
|   // onExpandedRowsChange: PropTypes.func, | ||||
|   columnManager: PropTypes.object.isRequired, | ||||
|   store: PropTypes.object.isRequired, | ||||
|   prefixCls: PropTypes.string.isRequired, | ||||
|   data: PropTypes.array, | ||||
|   getRowKey: PropTypes.func, | ||||
| }) | ||||
| 
 | ||||
| const ExpandableTable = { | ||||
|   name: 'ExpandableTable', | ||||
|   mixins: [BaseMixin], | ||||
|   props: initDefaultProps(ExpandableTableProps(), { | ||||
|     expandIconAsCell: false, | ||||
|     expandedRowClassName: () => '', | ||||
|     expandIconColumnIndex: 0, | ||||
|     defaultExpandAllRows: false, | ||||
|     defaultExpandedRowKeys: [], | ||||
|     childrenColumnName: 'children', | ||||
|     indentSize: 15, | ||||
|   }), | ||||
| 
 | ||||
|   data () { | ||||
|     const { | ||||
|       data, | ||||
|       childrenColumnName, | ||||
|       defaultExpandAllRows, | ||||
|       expandedRowKeys, | ||||
|       defaultExpandedRowKeys, | ||||
|       getRowKey, | ||||
|     } = this | ||||
| 
 | ||||
|     let finnalExpandedRowKeys = [] | ||||
|     let rows = [...data] | ||||
| 
 | ||||
|     if (defaultExpandAllRows) { | ||||
|       for (let i = 0; i < rows.length; i++) { | ||||
|         const row = rows[i] | ||||
|         finnalExpandedRowKeys.push(getRowKey(row, i)) | ||||
|         rows = rows.concat(row[childrenColumnName] || []) | ||||
|       } | ||||
|     } else { | ||||
|       finnalExpandedRowKeys = expandedRowKeys || defaultExpandedRowKeys | ||||
|     } | ||||
| 
 | ||||
|     // this.columnManager = props.columnManager | ||||
|     // this.store = props.store | ||||
| 
 | ||||
|     this.store.setState({ | ||||
|       expandedRowsHeight: {}, | ||||
|       expandedRowKeys: finnalExpandedRowKeys, | ||||
|     }) | ||||
|     return {} | ||||
|   }, | ||||
|   watch: { | ||||
|     expandedRowKeys (val) { | ||||
|       this.store.setState({ | ||||
|         expandedRowKeys: val, | ||||
|       }) | ||||
|     }, | ||||
|   }, | ||||
|   methods: { | ||||
|     handleExpandChange (expanded, record, event, rowKey, destroy = false) { | ||||
|       if (event) { | ||||
|         event.preventDefault() | ||||
|         event.stopPropagation() | ||||
|       } | ||||
| 
 | ||||
|       let { expandedRowKeys } = this.store.getState() | ||||
| 
 | ||||
|       if (expanded) { | ||||
|         // row was expaned | ||||
|         expandedRowKeys = [...expandedRowKeys, rowKey] | ||||
|       } else { | ||||
|         // row was collapse | ||||
|         const expandedRowIndex = expandedRowKeys.indexOf(rowKey) | ||||
|         if (expandedRowIndex !== -1) { | ||||
|           expandedRowKeys = remove(expandedRowKeys, rowKey) | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       if (!this.expandedRowKeys) { | ||||
|         this.store.setState({ expandedRowKeys }) | ||||
|       } | ||||
|       this.__emit('expandedRowsChange', expandedRowKeys) | ||||
|       if (!destroy) { | ||||
|         this.__emit('expand', expanded, record) | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     renderExpandIndentCell  (rows, fixed) { | ||||
|       const { prefixCls, expandIconAsCell } = this | ||||
|       if (!expandIconAsCell || fixed === 'right' || !rows.length) { | ||||
|         return | ||||
|       } | ||||
| 
 | ||||
|       const iconColumn = { | ||||
|         key: 'rc-table-expand-icon-cell', | ||||
|         className: `${prefixCls}-expand-icon-th`, | ||||
|         title: '', | ||||
|         rowSpan: rows.length, | ||||
|       } | ||||
| 
 | ||||
|       rows[0].unshift({ ...iconColumn, column: iconColumn }) | ||||
|     }, | ||||
| 
 | ||||
|     renderExpandedRow (record, index, render, className, ancestorKeys, indent, fixed) { | ||||
|       const { prefixCls, expandIconAsCell, indentSize } = this | ||||
|       let colCount | ||||
|       if (fixed === 'left') { | ||||
|         colCount = this.columnManager.leftLeafColumns().length | ||||
|       } else if (fixed === 'right') { | ||||
|         colCount = this.columnManager.rightLeafColumns().length | ||||
|       } else { | ||||
|         colCount = this.columnManager.leafColumns().length | ||||
|       } | ||||
|       const columns = [{ | ||||
|         key: 'extra-row', | ||||
|         render: () => ({ | ||||
|           props: { | ||||
|             colSpan: colCount, | ||||
|           }, | ||||
|           children: fixed !== 'right' ? render(record, index, indent) : ' ', | ||||
|         }), | ||||
|       }] | ||||
|       if (expandIconAsCell && fixed !== 'right') { | ||||
|         columns.unshift({ | ||||
|           key: 'expand-icon-placeholder', | ||||
|           render: () => null, | ||||
|         }) | ||||
|       } | ||||
|       const parentKey = ancestorKeys[ancestorKeys.length - 1] | ||||
|       const rowKey = `${parentKey}-extra-row` | ||||
|       const components = { | ||||
|         body: { | ||||
|           row: 'tr', | ||||
|           cell: 'td', | ||||
|         }, | ||||
|       } | ||||
| 
 | ||||
|       return ( | ||||
|         <TableRow | ||||
|           key={rowKey} | ||||
|           columns={columns} | ||||
|           className={className} | ||||
|           rowKey={rowKey} | ||||
|           ancestorKeys={ancestorKeys} | ||||
|           prefixCls={`${prefixCls}-expanded-row`} | ||||
|           indentSize={indentSize} | ||||
|           indent={indent} | ||||
|           fixed={fixed} | ||||
|           components={components} | ||||
|           expandedRow | ||||
|         /> | ||||
|       ) | ||||
|     }, | ||||
| 
 | ||||
|     renderRows  (renderRows, rows, record, index, indent, fixed, parentKey, ancestorKeys) { | ||||
|       const { expandedRowClassName, expandedRowRender, childrenColumnName } = this | ||||
|       const childrenData = record[childrenColumnName] | ||||
|       const nextAncestorKeys = [...ancestorKeys, parentKey] | ||||
|       const nextIndent = indent + 1 | ||||
| 
 | ||||
|       if (expandedRowRender) { | ||||
|         rows.push( | ||||
|           this.renderExpandedRow( | ||||
|             record, | ||||
|             index, | ||||
|             expandedRowRender, | ||||
|             expandedRowClassName(record, index, indent), | ||||
|             nextAncestorKeys, | ||||
|             nextIndent, | ||||
|             fixed, | ||||
|           ), | ||||
|         ) | ||||
|       } | ||||
| 
 | ||||
|       if (childrenData) { | ||||
|         rows.push( | ||||
|           ...renderRows( | ||||
|             childrenData, | ||||
|             nextIndent, | ||||
|             nextAncestorKeys, | ||||
|           ) | ||||
|         ) | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
| 
 | ||||
|   render () { | ||||
|     const { data, childrenColumnName, $scopedSlots, $listeners } = this | ||||
|     const props = getOptionProps(this) | ||||
|     const needIndentSpaced = data.some(record => record[childrenColumnName]) | ||||
| 
 | ||||
|     return $scopedSlots.default && $scopedSlots.default({ | ||||
|       props, | ||||
|       on: $listeners, | ||||
|       needIndentSpaced, | ||||
|       renderRows: this.renderRows, | ||||
|       handleExpandChange: this.handleExpandChange, | ||||
|       renderExpandIndentCell: this.renderExpandIndentCell, | ||||
|     }) | ||||
|   }, | ||||
| } | ||||
| 
 | ||||
| export default connect()(ExpandableTable) | ||||
|  | @ -14,6 +14,9 @@ export default { | |||
|     handleBodyScrollLeft: PropTypes.func.isRequired, | ||||
|     expander: PropTypes.object.isRequired, | ||||
|   }, | ||||
|   inject: { | ||||
|     table: { default: {}}, | ||||
|   }, | ||||
|   render () { | ||||
|     const { columns, fixed, tableClassName, handleBodyScrollLeft, expander, table } = this | ||||
|     const { prefixCls, scroll, showHeader } = table | ||||
|  |  | |||
|  | @ -1,475 +0,0 @@ | |||
| import React from 'react' | ||||
| import PropTypes from 'prop-types' | ||||
| import { debounce, warningOnce } from './utils' | ||||
| import shallowequal from 'shallowequal' | ||||
| import addEventListener from 'rc-util/lib/Dom/addEventListener' | ||||
| import { Provider, create } from 'mini-store' | ||||
| import merge from 'lodash/merge' | ||||
| import ColumnManager from './ColumnManager' | ||||
| import classes from 'component-classes' | ||||
| import HeadTable from './HeadTable' | ||||
| import BodyTable from './BodyTable' | ||||
| import ExpandableTable from './ExpandableTable' | ||||
| 
 | ||||
| export default class Table extends React.Component { | ||||
|   static propTypes = { | ||||
|     data: PropTypes.array, | ||||
|     useFixedHeader: PropTypes.bool, | ||||
|     columns: PropTypes.array, | ||||
|     prefixCls: PropTypes.string, | ||||
|     bodyStyle: PropTypes.object, | ||||
|     style: PropTypes.object, | ||||
|     rowKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), | ||||
|     rowClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), | ||||
|     onRow: PropTypes.func, | ||||
|     onHeaderRow: PropTypes.func, | ||||
|     onRowClick: PropTypes.func, | ||||
|     onRowDoubleClick: PropTypes.func, | ||||
|     onRowContextMenu: PropTypes.func, | ||||
|     onRowMouseEnter: PropTypes.func, | ||||
|     onRowMouseLeave: PropTypes.func, | ||||
|     showHeader: PropTypes.bool, | ||||
|     title: PropTypes.func, | ||||
|     id: PropTypes.string, | ||||
|     footer: PropTypes.func, | ||||
|     emptyText: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), | ||||
|     scroll: PropTypes.object, | ||||
|     rowRef: PropTypes.func, | ||||
|     getBodyWrapper: PropTypes.func, | ||||
|     children: PropTypes.node, | ||||
|     components: PropTypes.shape({ | ||||
|       table: PropTypes.any, | ||||
|       header: PropTypes.shape({ | ||||
|         wrapper: PropTypes.any, | ||||
|         row: PropTypes.any, | ||||
|         cell: PropTypes.any, | ||||
|       }), | ||||
|       body: PropTypes.shape({ | ||||
|         wrapper: PropTypes.any, | ||||
|         row: PropTypes.any, | ||||
|         cell: PropTypes.any, | ||||
|       }), | ||||
|     }), | ||||
|     ...ExpandableTable.PropTypes, | ||||
|   } | ||||
| 
 | ||||
|   static childContextTypes = { | ||||
|     table: PropTypes.any, | ||||
|     components: PropTypes.any, | ||||
|   } | ||||
| 
 | ||||
|   static defaultProps = { | ||||
|     data: [], | ||||
|     useFixedHeader: false, | ||||
|     rowKey: 'key', | ||||
|     rowClassName: () => '', | ||||
|     onRow () {}, | ||||
|     onHeaderRow () {}, | ||||
|     prefixCls: 'rc-table', | ||||
|     bodyStyle: {}, | ||||
|     style: {}, | ||||
|     showHeader: true, | ||||
|     scroll: {}, | ||||
|     rowRef: () => null, | ||||
|     emptyText: () => 'No Data', | ||||
|   } | ||||
| 
 | ||||
|   constructor (props) { | ||||
|     super(props); | ||||
| 
 | ||||
|     [ | ||||
|       'onRowClick', | ||||
|       'onRowDoubleClick', | ||||
|       'onRowContextMenu', | ||||
|       'onRowMouseEnter', | ||||
|       'onRowMouseLeave', | ||||
|     ].forEach(name => { | ||||
|       warningOnce( | ||||
|         props[name] === undefined, | ||||
|         `${name} is deprecated, please use onRow instead.`, | ||||
|       ) | ||||
|     }) | ||||
| 
 | ||||
|     warningOnce( | ||||
|       props.getBodyWrapper === undefined, | ||||
|       'getBodyWrapper is deprecated, please use custom components instead.', | ||||
|     ) | ||||
| 
 | ||||
|     this.columnManager = new ColumnManager(props.columns, props.children) | ||||
| 
 | ||||
|     this.store = create({ | ||||
|       currentHoverKey: null, | ||||
|       fixedColumnsHeadRowsHeight: [], | ||||
|       fixedColumnsBodyRowsHeight: [], | ||||
|     }) | ||||
| 
 | ||||
|     this.setScrollPosition('left') | ||||
| 
 | ||||
|     this.debouncedWindowResize = debounce(this.handleWindowResize, 150) | ||||
|   } | ||||
| 
 | ||||
|   getChildContext () { | ||||
|     return { | ||||
|       table: { | ||||
|         props: this.props, | ||||
|         columnManager: this.columnManager, | ||||
|         saveRef: this.saveRef, | ||||
|         components: merge({ | ||||
|           table: 'table', | ||||
|           header: { | ||||
|             wrapper: 'thead', | ||||
|             row: 'tr', | ||||
|             cell: 'th', | ||||
|           }, | ||||
|           body: { | ||||
|             wrapper: 'tbody', | ||||
|             row: 'tr', | ||||
|             cell: 'td', | ||||
|           }, | ||||
|         }, this.props.components), | ||||
|       }, | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   componentDidMount () { | ||||
|     if (this.columnManager.isAnyColumnsFixed()) { | ||||
|       this.handleWindowResize() | ||||
|       this.resizeEvent = addEventListener( | ||||
|         window, 'resize', this.debouncedWindowResize | ||||
|       ) | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   componentWillReceiveProps (nextProps) { | ||||
|     if (nextProps.columns && nextProps.columns !== this.props.columns) { | ||||
|       this.columnManager.reset(nextProps.columns) | ||||
|     } else if (nextProps.children !== this.props.children) { | ||||
|       this.columnManager.reset(null, nextProps.children) | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   componentDidUpdate (prevProps) { | ||||
|     if (this.columnManager.isAnyColumnsFixed()) { | ||||
|       this.handleWindowResize() | ||||
|       if (!this.resizeEvent) { | ||||
|         this.resizeEvent = addEventListener( | ||||
|           window, 'resize', this.debouncedWindowResize | ||||
|         ) | ||||
|       } | ||||
|     } | ||||
|     // when table changes to empty, reset scrollLeft
 | ||||
|     if (prevProps.data.length > 0 && this.props.data.length === 0 && this.hasScrollX()) { | ||||
|       this.resetScrollX() | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   componentWillUnmount () { | ||||
|     if (this.resizeEvent) { | ||||
|       this.resizeEvent.remove() | ||||
|     } | ||||
|     if (this.debouncedWindowResize) { | ||||
|       this.debouncedWindowResize.cancel() | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   getRowKey = (record, index) => { | ||||
|     const rowKey = this.props.rowKey | ||||
|     const key = (typeof rowKey === 'function') | ||||
|       ? rowKey(record, index) : record[rowKey] | ||||
|     warningOnce( | ||||
|       key !== undefined, | ||||
|       'Each record in table should have a unique `key` prop,' + | ||||
|       'or set `rowKey` to an unique primary key.' | ||||
|     ) | ||||
|     return key === undefined ? index : key | ||||
|   } | ||||
| 
 | ||||
|   setScrollPosition (position) { | ||||
|     this.scrollPosition = position | ||||
|     if (this.tableNode) { | ||||
|       const { prefixCls } = this.props | ||||
|       if (position === 'both') { | ||||
|         classes(this.tableNode) | ||||
|           .remove(new RegExp(`^${prefixCls}-scroll-position-.+$`)) | ||||
|           .add(`${prefixCls}-scroll-position-left`) | ||||
|           .add(`${prefixCls}-scroll-position-right`) | ||||
|       } else { | ||||
|         classes(this.tableNode) | ||||
|           .remove(new RegExp(`^${prefixCls}-scroll-position-.+$`)) | ||||
|           .add(`${prefixCls}-scroll-position-${position}`) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   setScrollPositionClassName () { | ||||
|     const node = this.bodyTable | ||||
|     const scrollToLeft = node.scrollLeft === 0 | ||||
|     const scrollToRight = node.scrollLeft + 1 >= | ||||
|       node.children[0].getBoundingClientRect().width - | ||||
|       node.getBoundingClientRect().width | ||||
|     if (scrollToLeft && scrollToRight) { | ||||
|       this.setScrollPosition('both') | ||||
|     } else if (scrollToLeft) { | ||||
|       this.setScrollPosition('left') | ||||
|     } else if (scrollToRight) { | ||||
|       this.setScrollPosition('right') | ||||
|     } else if (this.scrollPosition !== 'middle') { | ||||
|       this.setScrollPosition('middle') | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   handleWindowResize = () => { | ||||
|     this.syncFixedTableRowHeight() | ||||
|     this.setScrollPositionClassName() | ||||
|   } | ||||
| 
 | ||||
|   syncFixedTableRowHeight = () => { | ||||
|     const tableRect = this.tableNode.getBoundingClientRect() | ||||
|     // If tableNode's height less than 0, suppose it is hidden and don't recalculate rowHeight.
 | ||||
|     // see: https://github.com/ant-design/ant-design/issues/4836
 | ||||
|     if (tableRect.height !== undefined && tableRect.height <= 0) { | ||||
|       return | ||||
|     } | ||||
|     const { prefixCls } = this.props | ||||
|     const headRows = this.headTable | ||||
|       ? this.headTable.querySelectorAll('thead') | ||||
|       : this.bodyTable.querySelectorAll('thead') | ||||
|     const bodyRows = this.bodyTable.querySelectorAll(`.${prefixCls}-row`) || [] | ||||
|     const fixedColumnsHeadRowsHeight = [].map.call( | ||||
|       headRows, row => row.getBoundingClientRect().height || 'auto' | ||||
|     ) | ||||
|     const fixedColumnsBodyRowsHeight = [].map.call( | ||||
|       bodyRows, row => row.getBoundingClientRect().height || 'auto' | ||||
|     ) | ||||
|     const state = this.store.getState() | ||||
|     if (shallowequal(state.fixedColumnsHeadRowsHeight, fixedColumnsHeadRowsHeight) && | ||||
|         shallowequal(state.fixedColumnsBodyRowsHeight, fixedColumnsBodyRowsHeight)) { | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     this.store.setState({ | ||||
|       fixedColumnsHeadRowsHeight, | ||||
|       fixedColumnsBodyRowsHeight, | ||||
|     }) | ||||
|   } | ||||
| 
 | ||||
|   resetScrollX () { | ||||
|     if (this.headTable) { | ||||
|       this.headTable.scrollLeft = 0 | ||||
|     } | ||||
|     if (this.bodyTable) { | ||||
|       this.bodyTable.scrollLeft = 0 | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   hasScrollX () { | ||||
|     const { scroll = {}} = this.props | ||||
|     return 'x' in scroll | ||||
|   } | ||||
| 
 | ||||
|   handleBodyScrollLeft = (e) => { | ||||
|     // Fix https://github.com/ant-design/ant-design/issues/7635
 | ||||
|     if (e.currentTarget !== e.target) { | ||||
|       return | ||||
|     } | ||||
|     const target = e.target | ||||
|     const { scroll = {}} = this.props | ||||
|     const { headTable, bodyTable } = this | ||||
|     if (target.scrollLeft !== this.lastScrollLeft && scroll.x) { | ||||
|       if (target === bodyTable && headTable) { | ||||
|         headTable.scrollLeft = target.scrollLeft | ||||
|       } else if (target === headTable && bodyTable) { | ||||
|         bodyTable.scrollLeft = target.scrollLeft | ||||
|       } | ||||
|       this.setScrollPositionClassName() | ||||
|     } | ||||
|     // Remember last scrollLeft for scroll direction detecting.
 | ||||
|     this.lastScrollLeft = target.scrollLeft | ||||
|   } | ||||
| 
 | ||||
|   handleBodyScrollTop = (e) => { | ||||
|     const target = e.target | ||||
|     const { scroll = {}} = this.props | ||||
|     const { headTable, bodyTable, fixedColumnsBodyLeft, fixedColumnsBodyRight } = this | ||||
|     if (target.scrollTop !== this.lastScrollTop && scroll.y && target !== headTable) { | ||||
|       const scrollTop = target.scrollTop | ||||
|       if (fixedColumnsBodyLeft && target !== fixedColumnsBodyLeft) { | ||||
|         fixedColumnsBodyLeft.scrollTop = scrollTop | ||||
|       } | ||||
|       if (fixedColumnsBodyRight && target !== fixedColumnsBodyRight) { | ||||
|         fixedColumnsBodyRight.scrollTop = scrollTop | ||||
|       } | ||||
|       if (bodyTable && target !== bodyTable) { | ||||
|         bodyTable.scrollTop = scrollTop | ||||
|       } | ||||
|     } | ||||
|     // Remember last scrollTop for scroll direction detecting.
 | ||||
|     this.lastScrollTop = target.scrollTop | ||||
|   } | ||||
| 
 | ||||
|   handleBodyScroll = (e) => { | ||||
|     this.handleBodyScrollLeft(e) | ||||
|     this.handleBodyScrollTop(e) | ||||
|   } | ||||
| 
 | ||||
|   saveRef = (name) => (node) => { | ||||
|     this[name] = node | ||||
|   } | ||||
| 
 | ||||
|   renderMainTable () { | ||||
|     const { scroll, prefixCls } = this.props | ||||
|     const isAnyColumnsFixed = this.columnManager.isAnyColumnsFixed() | ||||
|     const scrollable = isAnyColumnsFixed || scroll.x || scroll.y | ||||
| 
 | ||||
|     const table = [ | ||||
|       this.renderTable({ | ||||
|         columns: this.columnManager.groupedColumns(), | ||||
|         isAnyColumnsFixed, | ||||
|       }), | ||||
|       this.renderEmptyText(), | ||||
|       this.renderFooter(), | ||||
|     ] | ||||
| 
 | ||||
|     return scrollable ? ( | ||||
|       <div className={`${prefixCls}-scroll`}>{table}</div> | ||||
|     ) : table | ||||
|   } | ||||
| 
 | ||||
|   renderLeftFixedTable () { | ||||
|     const { prefixCls } = this.props | ||||
| 
 | ||||
|     return ( | ||||
|       <div className={`${prefixCls}-fixed-left`}> | ||||
|         {this.renderTable({ | ||||
|           columns: this.columnManager.leftColumns(), | ||||
|           fixed: 'left', | ||||
|         })} | ||||
|       </div> | ||||
|     ) | ||||
|   } | ||||
| 
 | ||||
|   renderRightFixedTable () { | ||||
|     const { prefixCls } = this.props | ||||
| 
 | ||||
|     return ( | ||||
|       <div className={`${prefixCls}-fixed-right`}> | ||||
|         {this.renderTable({ | ||||
|           columns: this.columnManager.rightColumns(), | ||||
|           fixed: 'right', | ||||
|         })} | ||||
|       </div> | ||||
|     ) | ||||
|   } | ||||
| 
 | ||||
|   renderTable (options) { | ||||
|     const { columns, fixed, isAnyColumnsFixed } = options | ||||
|     const { prefixCls, scroll = {}} = this.props | ||||
|     const tableClassName = (scroll.x || fixed) ? `${prefixCls}-fixed` : '' | ||||
| 
 | ||||
|     const headTable = ( | ||||
|       <HeadTable | ||||
|         key='head' | ||||
|         columns={columns} | ||||
|         fixed={fixed} | ||||
|         tableClassName={tableClassName} | ||||
|         handleBodyScrollLeft={this.handleBodyScrollLeft} | ||||
|         expander={this.expander} | ||||
|       /> | ||||
|     ) | ||||
| 
 | ||||
|     const bodyTable = ( | ||||
|       <BodyTable | ||||
|         key='body' | ||||
|         columns={columns} | ||||
|         fixed={fixed} | ||||
|         tableClassName={tableClassName} | ||||
|         getRowKey={this.getRowKey} | ||||
|         handleBodyScroll={this.handleBodyScroll} | ||||
|         expander={this.expander} | ||||
|         isAnyColumnsFixed={isAnyColumnsFixed} | ||||
|       /> | ||||
|     ) | ||||
| 
 | ||||
|     return [headTable, bodyTable] | ||||
|   } | ||||
| 
 | ||||
|   renderTitle () { | ||||
|     const { title, prefixCls } = this.props | ||||
|     return title ? ( | ||||
|       <div className={`${prefixCls}-title`} key='title'> | ||||
|         {title(this.props.data)} | ||||
|       </div> | ||||
|     ) : null | ||||
|   } | ||||
| 
 | ||||
|   renderFooter () { | ||||
|     const { footer, prefixCls } = this.props | ||||
|     return footer ? ( | ||||
|       <div className={`${prefixCls}-footer`} key='footer'> | ||||
|         {footer(this.props.data)} | ||||
|       </div> | ||||
|     ) : null | ||||
|   } | ||||
| 
 | ||||
|   renderEmptyText () { | ||||
|     const { emptyText, prefixCls, data } = this.props | ||||
|     if (data.length) { | ||||
|       return null | ||||
|     } | ||||
|     const emptyClassName = `${prefixCls}-placeholder` | ||||
|     return ( | ||||
|       <div className={emptyClassName} key='emptyText'> | ||||
|         {(typeof emptyText === 'function') ? emptyText() : emptyText} | ||||
|       </div> | ||||
|     ) | ||||
|   } | ||||
| 
 | ||||
|   render () { | ||||
|     const props = this.props | ||||
|     const prefixCls = props.prefixCls | ||||
| 
 | ||||
|     let className = props.prefixCls | ||||
|     if (props.className) { | ||||
|       className += ` ${props.className}` | ||||
|     } | ||||
|     if (props.useFixedHeader || (props.scroll && props.scroll.y)) { | ||||
|       className += ` ${prefixCls}-fixed-header` | ||||
|     } | ||||
|     if (this.scrollPosition === 'both') { | ||||
|       className += ` ${prefixCls}-scroll-position-left ${prefixCls}-scroll-position-right` | ||||
|     } else { | ||||
|       className += ` ${prefixCls}-scroll-position-${this.scrollPosition}` | ||||
|     } | ||||
|     const hasLeftFixed = this.columnManager.isAnyColumnsLeftFixed() | ||||
|     const hasRightFixed = this.columnManager.isAnyColumnsRightFixed() | ||||
| 
 | ||||
|     return ( | ||||
|       <Provider store={this.store}> | ||||
|         <ExpandableTable | ||||
|           {...props} | ||||
|           columnManager={this.columnManager} | ||||
|           getRowKey={this.getRowKey} | ||||
|         > | ||||
|           {(expander) => { | ||||
|             this.expander = expander | ||||
|             return ( | ||||
|               <div | ||||
|                 ref={this.saveRef('tableNode')} | ||||
|                 className={className} | ||||
|                 style={props.style} | ||||
|                 id={props.id} | ||||
|               > | ||||
|                 {this.renderTitle()} | ||||
|                 <div className={`${prefixCls}-content`}> | ||||
|                   {this.renderMainTable()} | ||||
|                   {hasLeftFixed && this.renderLeftFixedTable()} | ||||
|                   {hasRightFixed && this.renderRightFixedTable()} | ||||
|                 </div> | ||||
|               </div> | ||||
|             ) | ||||
|           }} | ||||
|         </ExpandableTable> | ||||
|       </Provider> | ||||
|     ) | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,507 @@ | |||
| 
 | ||||
| import PropTypes from '../../_util/vue-types' | ||||
| import { debounce, warningOnce } from './utils' | ||||
| import shallowequal from 'shallowequal' | ||||
| import addEventListener from '../../_util/Dom/addEventListener' | ||||
| import { Provider, create } from '../../_util/store' | ||||
| import merge from 'lodash/merge' | ||||
| import ColumnManager from './ColumnManager' | ||||
| import classes from 'component-classes' | ||||
| import HeadTable from './HeadTable' | ||||
| import BodyTable from './BodyTable' | ||||
| import ExpandableTable from './ExpandableTable' | ||||
| import { initDefaultProps, getOptionProps } from '../../_util/props-util' | ||||
| import BaseMixin from '../../_util/BaseMixin' | ||||
| 
 | ||||
| export default { | ||||
|   name: 'Table', | ||||
|   mixins: [BaseMixin], | ||||
|   props: initDefaultProps({ | ||||
|     data: PropTypes.array, | ||||
|     useFixedHeader: PropTypes.bool, | ||||
|     columns: PropTypes.array, | ||||
|     prefixCls: PropTypes.string, | ||||
|     bodyStyle: PropTypes.object, | ||||
|     rowKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), | ||||
|     rowClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), | ||||
|     // onRow: PropTypes.func, | ||||
|     // onHeaderRow: PropTypes.func, | ||||
|     // onRowClick: PropTypes.func, | ||||
|     // onRowDoubleClick: PropTypes.func, | ||||
|     // onRowContextMenu: PropTypes.func, | ||||
|     // onRowMouseEnter: PropTypes.func, | ||||
|     // onRowMouseLeave: PropTypes.func, | ||||
|     showHeader: PropTypes.bool, | ||||
|     title: PropTypes.func, | ||||
|     id: PropTypes.string, | ||||
|     footer: PropTypes.func, | ||||
|     emptyText: PropTypes.any, | ||||
|     scroll: PropTypes.object, | ||||
|     rowRef: PropTypes.func, | ||||
|     getBodyWrapper: PropTypes.func, | ||||
|     components: PropTypes.shape({ | ||||
|       table: PropTypes.any, | ||||
|       header: PropTypes.shape({ | ||||
|         wrapper: PropTypes.any, | ||||
|         row: PropTypes.any, | ||||
|         cell: PropTypes.any, | ||||
|       }), | ||||
|       body: PropTypes.shape({ | ||||
|         wrapper: PropTypes.any, | ||||
|         row: PropTypes.any, | ||||
|         cell: PropTypes.any, | ||||
|       }), | ||||
|     }), | ||||
|     expandIconAsCell: PropTypes.bool, | ||||
|     expandedRowKeys: PropTypes.array, | ||||
|     expandedRowClassName: PropTypes.func, | ||||
|     defaultExpandAllRows: PropTypes.bool, | ||||
|     defaultExpandedRowKeys: PropTypes.array, | ||||
|     expandIconColumnIndex: PropTypes.number, | ||||
|     expandedRowRender: PropTypes.func, | ||||
|     childrenColumnName: PropTypes.string, | ||||
|     indentSize: PropTypes.number, | ||||
|   }, { | ||||
|     data: [], | ||||
|     useFixedHeader: false, | ||||
|     rowKey: 'key', | ||||
|     rowClassName: () => '', | ||||
|     prefixCls: 'rc-table', | ||||
|     bodyStyle: {}, | ||||
|     showHeader: true, | ||||
|     scroll: {}, | ||||
|     rowRef: () => null, | ||||
|     emptyText: () => 'No Data', | ||||
|   }), | ||||
| 
 | ||||
|   // static childContextTypes = { | ||||
|   //   table: PropTypes.any, | ||||
|   //   components: PropTypes.any, | ||||
|   // }, | ||||
| 
 | ||||
|   created () { | ||||
|     [ | ||||
|       'rowClick', | ||||
|       'rowDoubleclick', | ||||
|       'rowContextmenu', | ||||
|       'rowMouseenter', | ||||
|       'rowMouseleave', | ||||
|     ].forEach(name => { | ||||
|       warningOnce( | ||||
|         this.$listeners[name] === undefined, | ||||
|         `${name} is deprecated, please use onRow instead.`, | ||||
|       ) | ||||
|     }) | ||||
| 
 | ||||
|     warningOnce( | ||||
|       this.getBodyWrapper === undefined, | ||||
|       'getBodyWrapper is deprecated, please use custom components instead.', | ||||
|     ) | ||||
| 
 | ||||
|     // this.columnManager = new ColumnManager(this.columns, this.$slots.default) | ||||
| 
 | ||||
|     this.store = create({ | ||||
|       currentHoverKey: null, | ||||
|       fixedColumnsHeadRowsHeight: [], | ||||
|       fixedColumnsBodyRowsHeight: [], | ||||
|     }) | ||||
| 
 | ||||
|     this.setScrollPosition('left') | ||||
| 
 | ||||
|     this.debouncedWindowResize = debounce(this.handleWindowResize, 150) | ||||
|   }, | ||||
|   data () { | ||||
|     this.preData = [...this.data] | ||||
|     return { | ||||
|       columnManager: new ColumnManager(this.columns, this.$slots.default), | ||||
|       sComponents: merge({ | ||||
|         table: 'table', | ||||
|         header: { | ||||
|           wrapper: 'thead', | ||||
|           row: 'tr', | ||||
|           cell: 'th', | ||||
|         }, | ||||
|         body: { | ||||
|           wrapper: 'tbody', | ||||
|           row: 'tr', | ||||
|           cell: 'td', | ||||
|         }, | ||||
|       }, this.components), | ||||
|     } | ||||
|   }, | ||||
|   provide () { | ||||
|     return { | ||||
|       table: this, | ||||
|     } | ||||
|   }, | ||||
|   watch: { | ||||
|     components (val) { | ||||
|       this._components = merge({ | ||||
|         table: 'table', | ||||
|         header: { | ||||
|           wrapper: 'thead', | ||||
|           row: 'tr', | ||||
|           cell: 'th', | ||||
|         }, | ||||
|         body: { | ||||
|           wrapper: 'tbody', | ||||
|           row: 'tr', | ||||
|           cell: 'td', | ||||
|         }, | ||||
|       }, this.components) | ||||
|     }, | ||||
|     columns (val) { | ||||
|       if (val) { | ||||
|         this.columnManager.reset(val) | ||||
|       } | ||||
|     }, | ||||
|     data (val) { | ||||
|       if (val.length === 0 && this.hasScrollX()) { | ||||
|         this.$nextTick(() => { | ||||
|           this.resetScrollX() | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
| 
 | ||||
|   mounted () { | ||||
|     this.$nextTick(() => { | ||||
|       if (this.columnManager.isAnyColumnsFixed()) { | ||||
|         this.handleWindowResize() | ||||
|         this.resizeEvent = addEventListener( | ||||
|           window, 'resize', this.debouncedWindowResize | ||||
|         ) | ||||
|       } | ||||
|     }) | ||||
|   }, | ||||
| 
 | ||||
|   componentWillReceiveProps (nextProps) { | ||||
|     if (nextProps.columns && nextProps.columns !== this.props.columns) { | ||||
|       this.columnManager.reset(nextProps.columns) | ||||
|     } else if (nextProps.children !== this.props.children) { | ||||
|       this.columnManager.reset(null, nextProps.children) | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|   updated (prevProps) { | ||||
|     if (this.columnManager.isAnyColumnsFixed()) { | ||||
|       this.handleWindowResize() | ||||
|       if (!this.resizeEvent) { | ||||
|         this.resizeEvent = addEventListener( | ||||
|           window, 'resize', this.debouncedWindowResize | ||||
|         ) | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|   beforeDestroy () { | ||||
|     if (this.resizeEvent) { | ||||
|       this.resizeEvent.remove() | ||||
|     } | ||||
|     if (this.debouncedWindowResize) { | ||||
|       this.debouncedWindowResize.cancel() | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     getRowKey (record, index) { | ||||
|       const rowKey = this.rowKey | ||||
|       const key = (typeof rowKey === 'function') | ||||
|         ? rowKey(record, index) : record[rowKey] | ||||
|       warningOnce( | ||||
|         key !== undefined, | ||||
|         'Each record in table should have a unique `key` prop,' + | ||||
|         'or set `rowKey` to an unique primary key.' | ||||
|       ) | ||||
|       return key === undefined ? index : key | ||||
|     }, | ||||
| 
 | ||||
|     setScrollPosition (position) { | ||||
|       this.scrollPosition = position | ||||
|       if (this.tableNode) { | ||||
|         const { prefixCls } = this | ||||
|         if (position === 'both') { | ||||
|           classes(this.tableNode) | ||||
|             .remove(new RegExp(`^${prefixCls}-scroll-position-.+$`)) | ||||
|             .add(`${prefixCls}-scroll-position-left`) | ||||
|             .add(`${prefixCls}-scroll-position-right`) | ||||
|         } else { | ||||
|           classes(this.tableNode) | ||||
|             .remove(new RegExp(`^${prefixCls}-scroll-position-.+$`)) | ||||
|             .add(`${prefixCls}-scroll-position-${position}`) | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     setScrollPositionClassName () { | ||||
|       const node = this.bodyTable | ||||
|       const scrollToLeft = node.scrollLeft === 0 | ||||
|       const scrollToRight = node.scrollLeft + 1 >= | ||||
|         node.children[0].getBoundingClientRect().width - | ||||
|         node.getBoundingClientRect().width | ||||
|       if (scrollToLeft && scrollToRight) { | ||||
|         this.setScrollPosition('both') | ||||
|       } else if (scrollToLeft) { | ||||
|         this.setScrollPosition('left') | ||||
|       } else if (scrollToRight) { | ||||
|         this.setScrollPosition('right') | ||||
|       } else if (this.scrollPosition !== 'middle') { | ||||
|         this.setScrollPosition('middle') | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     handleWindowResize () { | ||||
|       this.syncFixedTableRowHeight() | ||||
|       this.setScrollPositionClassName() | ||||
|     }, | ||||
| 
 | ||||
|     syncFixedTableRowHeight () { | ||||
|       const tableRect = this.tableNode.getBoundingClientRect() | ||||
|       // If tableNode's height less than 0, suppose it is hidden and don't recalculate rowHeight. | ||||
|       // see: https://github.com/ant-design/ant-design/issues/4836 | ||||
|       if (tableRect.height !== undefined && tableRect.height <= 0) { | ||||
|         return | ||||
|       } | ||||
|       const { prefixCls } = this.props | ||||
|       const headRows = this.headTable | ||||
|         ? this.headTable.querySelectorAll('thead') | ||||
|         : this.bodyTable.querySelectorAll('thead') | ||||
|       const bodyRows = this.bodyTable.querySelectorAll(`.${prefixCls}-row`) || [] | ||||
|       const fixedColumnsHeadRowsHeight = [].map.call( | ||||
|         headRows, row => row.getBoundingClientRect().height || 'auto' | ||||
|       ) | ||||
|       const fixedColumnsBodyRowsHeight = [].map.call( | ||||
|         bodyRows, row => row.getBoundingClientRect().height || 'auto' | ||||
|       ) | ||||
|       const state = this.store.getState() | ||||
|       if (shallowequal(state.fixedColumnsHeadRowsHeight, fixedColumnsHeadRowsHeight) && | ||||
|           shallowequal(state.fixedColumnsBodyRowsHeight, fixedColumnsBodyRowsHeight)) { | ||||
|         return | ||||
|       } | ||||
| 
 | ||||
|       this.store.setState({ | ||||
|         fixedColumnsHeadRowsHeight, | ||||
|         fixedColumnsBodyRowsHeight, | ||||
|       }) | ||||
|     }, | ||||
| 
 | ||||
|     resetScrollX () { | ||||
|       if (this.headTable) { | ||||
|         this.headTable.scrollLeft = 0 | ||||
|       } | ||||
|       if (this.bodyTable) { | ||||
|         this.bodyTable.scrollLeft = 0 | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     hasScrollX () { | ||||
|       const { scroll = {}} = this | ||||
|       return 'x' in scroll | ||||
|     }, | ||||
| 
 | ||||
|     handleBodyScrollLeft  (e) { | ||||
|       // Fix https://github.com/ant-design/ant-design/issues/7635 | ||||
|       if (e.currentTarget !== e.target) { | ||||
|         return | ||||
|       } | ||||
|       const target = e.target | ||||
|       const { scroll = {}} = this | ||||
|       const { headTable, bodyTable } = this | ||||
|       if (target.scrollLeft !== this.lastScrollLeft && scroll.x) { | ||||
|         if (target === bodyTable && headTable) { | ||||
|           headTable.scrollLeft = target.scrollLeft | ||||
|         } else if (target === headTable && bodyTable) { | ||||
|           bodyTable.scrollLeft = target.scrollLeft | ||||
|         } | ||||
|         this.setScrollPositionClassName() | ||||
|       } | ||||
|       // Remember last scrollLeft for scroll direction detecting. | ||||
|       this.lastScrollLeft = target.scrollLeft | ||||
|     }, | ||||
| 
 | ||||
|     handleBodyScrollTop  (e) { | ||||
|       const target = e.target | ||||
|       const { scroll = {}} = this | ||||
|       const { headTable, bodyTable, fixedColumnsBodyLeft, fixedColumnsBodyRight } = this | ||||
|       if (target.scrollTop !== this.lastScrollTop && scroll.y && target !== headTable) { | ||||
|         const scrollTop = target.scrollTop | ||||
|         if (fixedColumnsBodyLeft && target !== fixedColumnsBodyLeft) { | ||||
|           fixedColumnsBodyLeft.scrollTop = scrollTop | ||||
|         } | ||||
|         if (fixedColumnsBodyRight && target !== fixedColumnsBodyRight) { | ||||
|           fixedColumnsBodyRight.scrollTop = scrollTop | ||||
|         } | ||||
|         if (bodyTable && target !== bodyTable) { | ||||
|           bodyTable.scrollTop = scrollTop | ||||
|         } | ||||
|       } | ||||
|       // Remember last scrollTop for scroll direction detecting. | ||||
|       this.lastScrollTop = target.scrollTop | ||||
|     }, | ||||
| 
 | ||||
|     handleBodyScroll (e) { | ||||
|       this.handleBodyScrollLeft(e) | ||||
|       this.handleBodyScrollTop(e) | ||||
|     }, | ||||
| 
 | ||||
|     renderMainTable () { | ||||
|       const { scroll, prefixCls } = this | ||||
|       const isAnyColumnsFixed = this.columnManager.isAnyColumnsFixed() | ||||
|       const scrollable = isAnyColumnsFixed || scroll.x || scroll.y | ||||
| 
 | ||||
|       const table = [ | ||||
|         this.renderTable({ | ||||
|           columns: this.columnManager.groupedColumns(), | ||||
|           isAnyColumnsFixed, | ||||
|         }), | ||||
|         this.renderEmptyText(), | ||||
|         this.renderFooter(), | ||||
|       ] | ||||
| 
 | ||||
|       return scrollable ? ( | ||||
|         <div class={`${prefixCls}-scroll`}>{table}</div> | ||||
|       ) : table | ||||
|     }, | ||||
| 
 | ||||
|     renderLeftFixedTable () { | ||||
|       const { prefixCls } = this | ||||
| 
 | ||||
|       return ( | ||||
|         <div class={`${prefixCls}-fixed-left`}> | ||||
|           {this.renderTable({ | ||||
|             columns: this.columnManager.leftColumns(), | ||||
|             fixed: 'left', | ||||
|           })} | ||||
|         </div> | ||||
|       ) | ||||
|     }, | ||||
|     renderRightFixedTable () { | ||||
|       const { prefixCls } = this | ||||
| 
 | ||||
|       return ( | ||||
|         <div class={`${prefixCls}-fixed-right`}> | ||||
|           {this.renderTable({ | ||||
|             columns: this.columnManager.rightColumns(), | ||||
|             fixed: 'right', | ||||
|           })} | ||||
|         </div> | ||||
|       ) | ||||
|     }, | ||||
| 
 | ||||
|     renderTable (options) { | ||||
|       const { columns, fixed, isAnyColumnsFixed } = options | ||||
|       const { prefixCls, scroll = {}} = this | ||||
|       const tableClassName = (scroll.x || fixed) ? `${prefixCls}-fixed` : '' | ||||
| 
 | ||||
|       const headTable = ( | ||||
|         <HeadTable | ||||
|           key='head' | ||||
|           columns={columns} | ||||
|           fixed={fixed} | ||||
|           tableClassName={tableClassName} | ||||
|           handleBodyScrollLeft={this.handleBodyScrollLeft} | ||||
|           expander={this.expander} | ||||
|         /> | ||||
|       ) | ||||
| 
 | ||||
|       const bodyTable = ( | ||||
|         <BodyTable | ||||
|           key='body' | ||||
|           columns={columns} | ||||
|           fixed={fixed} | ||||
|           tableClassName={tableClassName} | ||||
|           getRowKey={this.getRowKey} | ||||
|           handleBodyScroll={this.handleBodyScroll} | ||||
|           expander={this.expander} | ||||
|           isAnyColumnsFixed={isAnyColumnsFixed} | ||||
|         /> | ||||
|       ) | ||||
| 
 | ||||
|       return [headTable, bodyTable] | ||||
|     }, | ||||
| 
 | ||||
|     renderTitle () { | ||||
|       const { title, prefixCls } = this | ||||
|       return title ? ( | ||||
|         <div class={`${prefixCls}-title`} key='title'> | ||||
|           {title(this.props.data)} | ||||
|         </div> | ||||
|       ) : null | ||||
|     }, | ||||
| 
 | ||||
|     renderFooter () { | ||||
|       const { footer, prefixCls } = this | ||||
|       return footer ? ( | ||||
|         <div class={`${prefixCls}-footer`} key='footer'> | ||||
|           {footer(this.props.data)} | ||||
|         </div> | ||||
|       ) : null | ||||
|     }, | ||||
| 
 | ||||
|     renderEmptyText () { | ||||
|       const { emptyText, prefixCls, data } = this | ||||
|       if (data.length) { | ||||
|         return null | ||||
|       } | ||||
|       const emptyClassName = `${prefixCls}-placeholder` | ||||
|       return ( | ||||
|         <div class={emptyClassName} key='emptyText'> | ||||
|           {(typeof emptyText === 'function') ? emptyText() : emptyText} | ||||
|         </div> | ||||
|       ) | ||||
|     }, | ||||
|   }, | ||||
| 
 | ||||
|   render () { | ||||
|     const props = getOptionProps(this) | ||||
|     const { $listeners, columnManager, getRowKey } = this | ||||
|     const prefixCls = props.prefixCls | ||||
| 
 | ||||
|     let className = props.prefixCls | ||||
|     if (props.useFixedHeader || (props.scroll && props.scroll.y)) { | ||||
|       className += ` ${prefixCls}-fixed-header` | ||||
|     } | ||||
|     if (this.scrollPosition === 'both') { | ||||
|       className += ` ${prefixCls}-scroll-position-left ${prefixCls}-scroll-position-right` | ||||
|     } else { | ||||
|       className += ` ${prefixCls}-scroll-position-${this.scrollPosition}` | ||||
|     } | ||||
|     const hasLeftFixed = columnManager.isAnyColumnsLeftFixed() | ||||
|     const hasRightFixed = columnManager.isAnyColumnsRightFixed() | ||||
| 
 | ||||
|     const expandableTableProps = { | ||||
|       props: { | ||||
|         ...props, | ||||
|         columnManager, | ||||
|         getRowKey, | ||||
|       }, | ||||
|       on: { ...$listeners }, | ||||
|       scopedSlots: { | ||||
|         default: (expander) => { | ||||
|           this.expander = expander | ||||
|           return ( | ||||
|             <div | ||||
|               ref='tableNode' | ||||
|               class={className} | ||||
|               // style={props.style} | ||||
|               // id={props.id} | ||||
|             > | ||||
|               {this.renderTitle()} | ||||
|               <div class={`${prefixCls}-content`}> | ||||
|                 {this.renderMainTable()} | ||||
|                 {hasLeftFixed && this.renderLeftFixedTable()} | ||||
|                 {hasRightFixed && this.renderRightFixedTable()} | ||||
|               </div> | ||||
|             </div> | ||||
|           ) | ||||
|         }, | ||||
|       }, | ||||
|     } | ||||
|     return ( | ||||
|       <Provider store={this.store}> | ||||
|         <ExpandableTable | ||||
|           {...expandableTableProps} | ||||
|         /> | ||||
|       </Provider> | ||||
|     ) | ||||
|   }, | ||||
| } | ||||
|  | @ -10,12 +10,12 @@ export default { | |||
|     indent: PropTypes.number, | ||||
|     indentSize: PropTypes.number, | ||||
|     column: PropTypes.object, | ||||
|     expandIcon: PropTypes.node, | ||||
|     expandIcon: PropTypes.any, | ||||
|     component: PropTypes.any, | ||||
|   }, | ||||
|   methods: { | ||||
|     isInvalidRenderCellText (text) { | ||||
|       debugger | ||||
|       // debugger | ||||
|       return text && | ||||
|         Object.prototype.toString.call(text) === '[object Object]' | ||||
|     }, | ||||
|  |  | |||
|  | @ -41,6 +41,9 @@ export default { | |||
|     expander: PropTypes.object.isRequired, | ||||
| 
 | ||||
|   }, | ||||
|   inject: { | ||||
|     table: { default: {}}, | ||||
|   }, | ||||
|   methods: { | ||||
|     onHeaderRow () { | ||||
|       this.table.__emit('headerRow', ...arguments) | ||||
|  | @ -48,7 +51,7 @@ export default { | |||
|   }, | ||||
| 
 | ||||
|   render () { | ||||
|     const { components, prefixCls, showHeader } = this.table | ||||
|     const { sComponents: components, prefixCls, showHeader } = this.table | ||||
|     const { expander, columns, fixed, onHeaderRow } = this | ||||
| 
 | ||||
|     if (!showHeader) { | ||||
|  |  | |||
|  | @ -1,53 +0,0 @@ | |||
| import React from 'react' | ||||
| import { connect } from 'mini-store' | ||||
| 
 | ||||
| function TableHeaderRow ({ row, index, height, components, onHeaderRow }) { | ||||
|   const HeaderRow = components.header.row | ||||
|   const HeaderCell = components.header.cell | ||||
|   const rowProps = onHeaderRow(row.map(cell => cell.column), index) | ||||
|   const customStyle = rowProps ? rowProps.style : {} | ||||
|   const style = { height, ...customStyle } | ||||
| 
 | ||||
|   return ( | ||||
|     <HeaderRow {...rowProps} style={style}> | ||||
|       {row.map((cell, i) => { | ||||
|         const { column, ...cellProps } = cell | ||||
|         const customProps = column.onHeaderCell ? column.onHeaderCell(column) : {} | ||||
|         if (column.align) { | ||||
|           cellProps.style = { textAlign: column.align } | ||||
|         } | ||||
|         return ( | ||||
|           <HeaderCell | ||||
|             {...cellProps} | ||||
|             {...customProps} | ||||
|             key={column.key || column.dataIndex || i} | ||||
|           /> | ||||
|         ) | ||||
|       })} | ||||
|     </HeaderRow> | ||||
|   ) | ||||
| } | ||||
| 
 | ||||
| function getRowHeight (state, props) { | ||||
|   const { fixedColumnsHeadRowsHeight } = state | ||||
|   const { columns, rows, fixed } = props | ||||
|   const headerHeight = fixedColumnsHeadRowsHeight[0] | ||||
| 
 | ||||
|   if (!fixed) { | ||||
|     return null | ||||
|   } | ||||
| 
 | ||||
|   if (headerHeight && columns) { | ||||
|     if (headerHeight === 'auto') { | ||||
|       return 'auto' | ||||
|     } | ||||
|     return headerHeight / rows.length | ||||
|   } | ||||
|   return null | ||||
| } | ||||
| 
 | ||||
| export default connect((state, props) => { | ||||
|   return { | ||||
|     height: getRowHeight(state, props), | ||||
|   } | ||||
| })(TableHeaderRow) | ||||
|  | @ -0,0 +1,71 @@ | |||
| import PropTypes from '../../_util/vue-types' | ||||
| import { connect } from '../../_util/store' | ||||
| 
 | ||||
| const TableHeaderRow = { | ||||
|   props: { | ||||
|     index: PropTypes.number, | ||||
|     fixed: PropTypes.string, | ||||
|     columns: PropTypes.array, | ||||
|     rows: PropTypes.array, | ||||
|     row: PropTypes.array, | ||||
|     components: PropTypes.object, | ||||
|     height: PropTypes.any, | ||||
|   }, | ||||
|   name: 'TableHeaderRow', | ||||
|   render () { | ||||
|     const { row, index, height, components, $listeners = {}} = this | ||||
|     const onHeaderRow = $listeners.headerRow | ||||
|     const HeaderRow = components.header.row | ||||
|     const HeaderCell = components.header.cell | ||||
|     const rowProps = onHeaderRow(row.map(cell => cell.column), index) | ||||
|     const customStyle = rowProps ? rowProps.style : {} | ||||
|     const style = { height, ...customStyle } | ||||
| 
 | ||||
|     return ( | ||||
|       <HeaderRow {...rowProps} style={style}> | ||||
|         {row.map((cell, i) => { | ||||
|           const { column, children, className, ...cellProps } = cell | ||||
|           const customProps = column.onHeaderCell ? column.onHeaderCell(column) : {} | ||||
|           if (column.align) { | ||||
|             cellProps.style = { textAlign: column.align } | ||||
|           } | ||||
| 
 | ||||
|           return ( | ||||
|             <HeaderCell | ||||
|               {...cellProps} | ||||
|               class={className} | ||||
|               {...customProps} | ||||
|               key={column.key || column.dataIndex || i} | ||||
|             > | ||||
|               {children} | ||||
|             </HeaderCell> | ||||
|           ) | ||||
|         })} | ||||
|       </HeaderRow> | ||||
|     ) | ||||
|   }, | ||||
| } | ||||
| 
 | ||||
| function getRowHeight (state, props) { | ||||
|   const { fixedColumnsHeadRowsHeight } = state | ||||
|   const { columns, rows, fixed } = props | ||||
|   const headerHeight = fixedColumnsHeadRowsHeight[0] | ||||
| 
 | ||||
|   if (!fixed) { | ||||
|     return null | ||||
|   } | ||||
| 
 | ||||
|   if (headerHeight && columns) { | ||||
|     if (headerHeight === 'auto') { | ||||
|       return 'auto' | ||||
|     } | ||||
|     return `${headerHeight / rows.length}px` | ||||
|   } | ||||
|   return null | ||||
| } | ||||
| 
 | ||||
| export default connect((state, props) => { | ||||
|   return { | ||||
|     height: getRowHeight(state, props), | ||||
|   } | ||||
| })(TableHeaderRow) | ||||
|  | @ -1,21 +1,23 @@ | |||
| import React from 'react' | ||||
| import ReactDOM from 'react-dom' | ||||
| import PropTypes from 'prop-types' | ||||
| import { connect } from 'mini-store' | ||||
| import PropTypes from '../../_util/vue-types' | ||||
| import { connect } from '../../_util/store' | ||||
| import TableCell from './TableCell' | ||||
| import { warningOnce } from './utils' | ||||
| import { initDefaultProps } from '../../_util/props-util' | ||||
| import BaseMixin from '../../_util/BaseMixin' | ||||
| 
 | ||||
| class TableRow extends React.Component { | ||||
|   static propTypes = { | ||||
|     onRow: PropTypes.func, | ||||
|     onRowClick: PropTypes.func, | ||||
|     onRowDoubleClick: PropTypes.func, | ||||
|     onRowContextMenu: PropTypes.func, | ||||
|     onRowMouseEnter: PropTypes.func, | ||||
|     onRowMouseLeave: PropTypes.func, | ||||
| const TableRow = { | ||||
|   name: 'TableRow', | ||||
|   mixins: [BaseMixin], | ||||
|   props: initDefaultProps({ | ||||
|     // onRow: PropTypes.func, | ||||
|     // onRowClick: PropTypes.func, | ||||
|     // onRowDoubleClick: PropTypes.func, | ||||
|     // onRowContextMenu: PropTypes.func, | ||||
|     // onRowMouseEnter: PropTypes.func, | ||||
|     // onRowMouseLeave: PropTypes.func, | ||||
|     record: PropTypes.object, | ||||
|     prefixCls: PropTypes.string, | ||||
|     onHover: PropTypes.func, | ||||
|     // onHover: PropTypes.func, | ||||
|     columns: PropTypes.array, | ||||
|     height: PropTypes.oneOfType([ | ||||
|       PropTypes.string, | ||||
|  | @ -43,133 +45,131 @@ class TableRow extends React.Component { | |||
|     expandedRow: PropTypes.bool, | ||||
|     isAnyColumnsFixed: PropTypes.bool, | ||||
|     ancestorKeys: PropTypes.array.isRequired, | ||||
|   } | ||||
| 
 | ||||
|   static defaultProps = { | ||||
|     onRow () {}, | ||||
|     expandIconColumnIndex: PropTypes.number, | ||||
|     expandRowByClick: PropTypes.bool, | ||||
|     // visible: PropTypes.bool, | ||||
|     // hovered: PropTypes.bool, | ||||
|     // height: PropTypes.any, | ||||
|   }, { | ||||
|     expandIconColumnIndex: 0, | ||||
|     expandRowByClick: false, | ||||
|     onHover () {}, | ||||
|     hasExpandIcon () {}, | ||||
|     renderExpandIcon () {}, | ||||
|     renderExpandIconCell () {}, | ||||
|   } | ||||
|   }), | ||||
| 
 | ||||
|   constructor (props) { | ||||
|     super(props) | ||||
|   data () { | ||||
|     this.shouldRender = this.visible | ||||
|     return {} | ||||
|   }, | ||||
| 
 | ||||
|     this.shouldRender = props.visible | ||||
|   } | ||||
| 
 | ||||
|   componentDidMount () { | ||||
|   mounted () { | ||||
|     if (this.shouldRender) { | ||||
|       this.saveRowRef() | ||||
|       this.$nextTick(() => { | ||||
|         this.saveRowRef() | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
|   }, | ||||
|   watch: { | ||||
| 
 | ||||
|   }, | ||||
| 
 | ||||
|   componentWillReceiveProps (nextProps) { | ||||
|     if (this.props.visible || (!this.props.visible && nextProps.visible)) { | ||||
|       this.shouldRender = true | ||||
|     } | ||||
|   } | ||||
|   }, | ||||
| 
 | ||||
|   shouldComponentUpdate (nextProps) { | ||||
|     return !!(this.props.visible || nextProps.visible) | ||||
|   } | ||||
|   }, | ||||
| 
 | ||||
|   componentDidUpdate () { | ||||
|   updated () { | ||||
|     if (this.shouldRender && !this.rowRef) { | ||||
|       this.saveRowRef() | ||||
|       this.$nextTick(() => { | ||||
|         this.saveRowRef() | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
|   }, | ||||
|   methods: { | ||||
|     onRowClick  (event) { | ||||
|       const { record, index } = this | ||||
|       this.__emit('rowClick', record, index, event) | ||||
|     }, | ||||
| 
 | ||||
|   onRowClick = (event) => { | ||||
|     const { record, index, onRowClick } = this.props | ||||
|     if (onRowClick) { | ||||
|       onRowClick(record, index, event) | ||||
|     } | ||||
|   } | ||||
|     onRowDoubleClick (event) { | ||||
|       const { record, index } = this | ||||
|       this.__emit('rowDoubleClick', record, index, event) | ||||
|     }, | ||||
| 
 | ||||
|   onRowDoubleClick = (event) => { | ||||
|     const { record, index, onRowDoubleClick } = this.props | ||||
|     if (onRowDoubleClick) { | ||||
|       onRowDoubleClick(record, index, event) | ||||
|     } | ||||
|   } | ||||
|     onContextMenu (event) { | ||||
|       const { record, index } = this | ||||
|       this.__emit('rowContextmenu', record, index, event) | ||||
|     }, | ||||
| 
 | ||||
|   onContextMenu = (event) => { | ||||
|     const { record, index, onRowContextMenu } = this.props | ||||
|     if (onRowContextMenu) { | ||||
|       onRowContextMenu(record, index, event) | ||||
|     } | ||||
|   } | ||||
|     onMouseEnter  (event) { | ||||
|       const { record, index, rowKey } = this | ||||
|       this.__emit('hover', true, rowKey) | ||||
|       this.__emit('rowMouseenter', record, index, event) | ||||
|     }, | ||||
| 
 | ||||
|   onMouseEnter = (event) => { | ||||
|     const { record, index, onRowMouseEnter, onHover, rowKey } = this.props | ||||
|     onHover(true, rowKey) | ||||
|     if (onRowMouseEnter) { | ||||
|       onRowMouseEnter(record, index, event) | ||||
|     } | ||||
|   } | ||||
|     onMouseLeave  (event) { | ||||
|       const { record, index, rowKey } = this | ||||
|       this.__emit('hover', false, rowKey) | ||||
|       this.__emit('rowMouseleave', record, index, event) | ||||
|     }, | ||||
| 
 | ||||
|   onMouseLeave = (event) => { | ||||
|     const { record, index, onRowMouseLeave, onHover, rowKey } = this.props | ||||
|     onHover(false, rowKey) | ||||
|     if (onRowMouseLeave) { | ||||
|       onRowMouseLeave(record, index, event) | ||||
|     } | ||||
|   } | ||||
|     setExpanedRowHeight () { | ||||
|       const { store, rowKey } = this | ||||
|       let { expandedRowsHeight } = store.getState() | ||||
|       const height = this.rowRef.getBoundingClientRect().height | ||||
|       expandedRowsHeight = { | ||||
|         ...expandedRowsHeight, | ||||
|         [rowKey]: height, | ||||
|       } | ||||
|       store.setState({ expandedRowsHeight }) | ||||
|     }, | ||||
| 
 | ||||
|   setExpanedRowHeight () { | ||||
|     const { store, rowKey } = this.props | ||||
|     let { expandedRowsHeight } = store.getState() | ||||
|     const height = this.rowRef.getBoundingClientRect().height | ||||
|     expandedRowsHeight = { | ||||
|       ...expandedRowsHeight, | ||||
|       [rowKey]: height, | ||||
|     } | ||||
|     store.setState({ expandedRowsHeight }) | ||||
|   } | ||||
|     setRowHeight () { | ||||
|       const { store, index } = this | ||||
|       const fixedColumnsBodyRowsHeight = store.getState().fixedColumnsBodyRowsHeight.slice() | ||||
|       const height = this.rowRef.getBoundingClientRect().height | ||||
|       fixedColumnsBodyRowsHeight[index] = height | ||||
|       store.setState({ fixedColumnsBodyRowsHeight }) | ||||
|     }, | ||||
| 
 | ||||
|   setRowHeight () { | ||||
|     const { store, index } = this.props | ||||
|     const fixedColumnsBodyRowsHeight = store.getState().fixedColumnsBodyRowsHeight.slice() | ||||
|     const height = this.rowRef.getBoundingClientRect().height | ||||
|     fixedColumnsBodyRowsHeight[index] = height | ||||
|     store.setState({ fixedColumnsBodyRowsHeight }) | ||||
|   } | ||||
|     getStyle () { | ||||
|       const { height, visible } = this | ||||
| 
 | ||||
|   getStyle () { | ||||
|     const { height, visible } = this.props | ||||
|       if (height && height !== this.style.height) { | ||||
|         this.style = { ...this.style, height } | ||||
|       } | ||||
| 
 | ||||
|     if (height && height !== this.style.height) { | ||||
|       this.style = { ...this.style, height } | ||||
|     } | ||||
|       if (!visible && !this.style.display) { | ||||
|         this.style = { ...this.style, display: 'none' } | ||||
|       } | ||||
| 
 | ||||
|     if (!visible && !this.style.display) { | ||||
|       this.style = { ...this.style, display: 'none' } | ||||
|     } | ||||
|       return this.style | ||||
|     }, | ||||
| 
 | ||||
|     return this.style | ||||
|   } | ||||
|     saveRowRef () { | ||||
|       this.rowRef = this.$el | ||||
| 
 | ||||
|   saveRowRef () { | ||||
|     this.rowRef = ReactDOM.findDOMNode(this) | ||||
|       const { isAnyColumnsFixed, fixed, expandedRow, ancestorKeys } = this | ||||
| 
 | ||||
|     const { isAnyColumnsFixed, fixed, expandedRow, ancestorKeys } = this.props | ||||
|       if (!isAnyColumnsFixed) { | ||||
|         return | ||||
|       } | ||||
| 
 | ||||
|     if (!isAnyColumnsFixed) { | ||||
|       return | ||||
|     } | ||||
|       if (!fixed && expandedRow) { | ||||
|         this.setExpanedRowHeight() | ||||
|       } | ||||
| 
 | ||||
|     if (!fixed && expandedRow) { | ||||
|       this.setExpanedRowHeight() | ||||
|     } | ||||
| 
 | ||||
|     if (!fixed && ancestorKeys.length >= 0) { | ||||
|       this.setRowHeight() | ||||
|     } | ||||
|   } | ||||
|       if (!fixed && ancestorKeys.length >= 0) { | ||||
|         this.setRowHeight() | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
| 
 | ||||
|   render () { | ||||
|     if (!this.shouldRender) { | ||||
|  | @ -181,7 +181,7 @@ class TableRow extends React.Component { | |||
|       columns, | ||||
|       record, | ||||
|       index, | ||||
|       onRow, | ||||
|       // onRow, | ||||
|       indent, | ||||
|       indentSize, | ||||
|       hovered, | ||||
|  | @ -191,12 +191,13 @@ class TableRow extends React.Component { | |||
|       hasExpandIcon, | ||||
|       renderExpandIcon, | ||||
|       renderExpandIconCell, | ||||
|     } = this.props | ||||
| 
 | ||||
|       $listeners, | ||||
|     } = this | ||||
|     const { row: onRow } = $listeners | ||||
|     const BodyRow = components.body.row | ||||
|     const BodyCell = components.body.cell | ||||
| 
 | ||||
|     let { className } = this.props | ||||
|     let className = '' | ||||
| 
 | ||||
|     if (hovered) { | ||||
|       className += ` ${prefixCls}-hover` | ||||
|  | @ -241,22 +242,22 @@ class TableRow extends React.Component { | |||
|     } | ||||
| 
 | ||||
|     style = { ...style, ...customStyle } | ||||
| 
 | ||||
|     console.log('rowProps', rowProps) | ||||
|     return ( | ||||
|       <BodyRow | ||||
|         onClick={this.onRowClick} | ||||
|         onDoubleClick={this.onRowDoubleClick} | ||||
|         onMouseEnter={this.onMouseEnter} | ||||
|         onMouseLeave={this.onMouseLeave} | ||||
|         onContextMenu={this.onContextMenu} | ||||
|         className={rowClassName} | ||||
|         onDoubleclick={this.onRowDoubleClick} | ||||
|         onMouseenter={this.onMouseEnter} | ||||
|         onMouseleave={this.onMouseLeave} | ||||
|         onContextmenu={this.onContextMenu} | ||||
|         class={rowClassName} | ||||
|         {...rowProps} | ||||
|         style={style} | ||||
|       > | ||||
|         {cells} | ||||
|       </BodyRow> | ||||
|     ) | ||||
|   } | ||||
|   }, | ||||
| } | ||||
| 
 | ||||
| function getRowHeight (state, props) { | ||||
|  | @ -3,7 +3,7 @@ const AsyncComp = () => { | |||
|   const hashs = window.location.hash.split('/') | ||||
|   const d = hashs[hashs.length - 1] | ||||
|   return { | ||||
|     component: import(`../components/vc-tree/demo/${d}`), | ||||
|     component: import(`../components/vc-table/demo/${d}`), | ||||
|   } | ||||
| } | ||||
| export default [ | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| { | ||||
|     "name": "vue-antd-ui", | ||||
|     "version": "0.1.0", | ||||
|     "version": "0.1.1", | ||||
|     "lockfileVersion": 1, | ||||
|     "requires": true, | ||||
|     "dependencies": { | ||||
|  | @ -206,7 +206,7 @@ | |||
|         }, | ||||
|         "abab": { | ||||
|             "version": "1.0.4", | ||||
|             "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", | ||||
|             "resolved": "http://registry.npm.taobao.org/abab/download/abab-1.0.4.tgz", | ||||
|             "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=", | ||||
|             "dev": true, | ||||
|             "optional": true | ||||
|  | @ -251,7 +251,7 @@ | |||
|         }, | ||||
|         "acorn-globals": { | ||||
|             "version": "1.0.9", | ||||
|             "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz", | ||||
|             "resolved": "http://registry.npm.taobao.org/acorn-globals/download/acorn-globals-1.0.9.tgz", | ||||
|             "integrity": "sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=", | ||||
|             "dev": true, | ||||
|             "optional": true, | ||||
|  | @ -261,7 +261,7 @@ | |||
|             "dependencies": { | ||||
|                 "acorn": { | ||||
|                     "version": "2.7.0", | ||||
|                     "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz", | ||||
|                     "resolved": "http://registry.npm.taobao.org/acorn/download/acorn-2.7.0.tgz", | ||||
|                     "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=", | ||||
|                     "dev": true, | ||||
|                     "optional": true | ||||
|  | @ -2491,7 +2491,7 @@ | |||
|         }, | ||||
|         "component-classes": { | ||||
|             "version": "1.2.6", | ||||
|             "resolved": "http://registry.npm.taobao.org/component-classes/download/component-classes-1.2.6.tgz", | ||||
|             "resolved": "https://registry.npmjs.org/component-classes/-/component-classes-1.2.6.tgz", | ||||
|             "integrity": "sha1-xkI5TDYYpNiwuJGe/Mu9kw5c1pE=", | ||||
|             "requires": { | ||||
|                 "component-indexof": "0.0.3" | ||||
|  | @ -3086,13 +3086,13 @@ | |||
|         }, | ||||
|         "cssom": { | ||||
|             "version": "0.3.2", | ||||
|             "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", | ||||
|             "resolved": "http://registry.npm.taobao.org/cssom/download/cssom-0.3.2.tgz", | ||||
|             "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=", | ||||
|             "dev": true | ||||
|         }, | ||||
|         "cssstyle": { | ||||
|             "version": "0.2.37", | ||||
|             "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", | ||||
|             "resolved": "http://registry.npm.taobao.org/cssstyle/download/cssstyle-0.2.37.tgz", | ||||
|             "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", | ||||
|             "dev": true, | ||||
|             "optional": true, | ||||
|  | @ -8076,7 +8076,7 @@ | |||
|         }, | ||||
|         "jsdom": { | ||||
|             "version": "7.2.2", | ||||
|             "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-7.2.2.tgz", | ||||
|             "resolved": "http://registry.npm.taobao.org/jsdom/download/jsdom-7.2.2.tgz", | ||||
|             "integrity": "sha1-QLQCdwwr2iNGkJa+6Rq2deOx/G4=", | ||||
|             "dev": true, | ||||
|             "optional": true, | ||||
|  | @ -8100,14 +8100,14 @@ | |||
|             "dependencies": { | ||||
|                 "acorn": { | ||||
|                     "version": "2.7.0", | ||||
|                     "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz", | ||||
|                     "resolved": "http://registry.npm.taobao.org/acorn/download/acorn-2.7.0.tgz", | ||||
|                     "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=", | ||||
|                     "dev": true, | ||||
|                     "optional": true | ||||
|                 }, | ||||
|                 "parse5": { | ||||
|                     "version": "1.5.1", | ||||
|                     "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", | ||||
|                     "resolved": "http://registry.npm.taobao.org/parse5/download/parse5-1.5.1.tgz", | ||||
|                     "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", | ||||
|                     "dev": true, | ||||
|                     "optional": true | ||||
|  | @ -8897,11 +8897,6 @@ | |||
|             "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", | ||||
|             "dev": true | ||||
|         }, | ||||
|         "lodash.clonedeep": { | ||||
|             "version": "4.5.0", | ||||
|             "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", | ||||
|             "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" | ||||
|         }, | ||||
|         "lodash.create": { | ||||
|             "version": "3.1.1", | ||||
|             "resolved": "https://registry.npm.taobao.org/lodash.create/download/lodash.create-3.1.1.tgz", | ||||
|  | @ -8913,11 +8908,6 @@ | |||
|                 "lodash._isiterateecall": "3.0.9" | ||||
|             } | ||||
|         }, | ||||
|         "lodash.debounce": { | ||||
|             "version": "4.0.8", | ||||
|             "resolved": "https://registry.npm.taobao.org/lodash.debounce/download/lodash.debounce-4.0.8.tgz", | ||||
|             "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" | ||||
|         }, | ||||
|         "lodash.escape": { | ||||
|             "version": "3.2.0", | ||||
|             "resolved": "http://registry.npm.taobao.org/lodash.escape/download/lodash.escape-3.2.0.tgz", | ||||
|  | @ -8945,11 +8935,6 @@ | |||
|             "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", | ||||
|             "dev": true | ||||
|         }, | ||||
|         "lodash.isequal": { | ||||
|             "version": "4.5.0", | ||||
|             "resolved": "https://registry.npm.taobao.org/lodash.isequal/download/lodash.isequal-4.5.0.tgz", | ||||
|             "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" | ||||
|         }, | ||||
|         "lodash.isplainobject": { | ||||
|             "version": "4.0.6", | ||||
|             "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", | ||||
|  | @ -15976,7 +15961,7 @@ | |||
|         }, | ||||
|         "symbol-tree": { | ||||
|             "version": "3.2.2", | ||||
|             "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", | ||||
|             "resolved": "http://registry.npm.taobao.org/symbol-tree/download/symbol-tree-3.2.2.tgz", | ||||
|             "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", | ||||
|             "dev": true, | ||||
|             "optional": true | ||||
|  | @ -16267,7 +16252,7 @@ | |||
|         }, | ||||
|         "tr46": { | ||||
|             "version": "0.0.3", | ||||
|             "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", | ||||
|             "resolved": "http://registry.npm.taobao.org/tr46/download/tr46-0.0.3.tgz", | ||||
|             "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", | ||||
|             "dev": true, | ||||
|             "optional": true | ||||
|  | @ -17031,7 +17016,7 @@ | |||
|             "dependencies": { | ||||
|                 "cheerio": { | ||||
|                     "version": "0.20.0", | ||||
|                     "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.20.0.tgz", | ||||
|                     "resolved": "http://registry.npm.taobao.org/cheerio/download/cheerio-0.20.0.tgz", | ||||
|                     "integrity": "sha1-XHEPK6uVZTJyhCugHG6mGzVF7DU=", | ||||
|                     "dev": true, | ||||
|                     "requires": { | ||||
|  | @ -17045,7 +17030,7 @@ | |||
|                 }, | ||||
|                 "domhandler": { | ||||
|                     "version": "2.3.0", | ||||
|                     "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", | ||||
|                     "resolved": "http://registry.npm.taobao.org/domhandler/download/domhandler-2.3.0.tgz", | ||||
|                     "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", | ||||
|                     "dev": true, | ||||
|                     "requires": { | ||||
|  | @ -17054,7 +17039,7 @@ | |||
|                 }, | ||||
|                 "domutils": { | ||||
|                     "version": "1.5.1", | ||||
|                     "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", | ||||
|                     "resolved": "http://registry.npm.taobao.org/domutils/download/domutils-1.5.1.tgz", | ||||
|                     "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", | ||||
|                     "dev": true, | ||||
|                     "requires": { | ||||
|  | @ -17064,7 +17049,7 @@ | |||
|                 }, | ||||
|                 "htmlparser2": { | ||||
|                     "version": "3.8.3", | ||||
|                     "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", | ||||
|                     "resolved": "http://registry.npm.taobao.org/htmlparser2/download/htmlparser2-3.8.3.tgz", | ||||
|                     "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", | ||||
|                     "dev": true, | ||||
|                     "requires": { | ||||
|  | @ -17077,7 +17062,7 @@ | |||
|                     "dependencies": { | ||||
|                         "entities": { | ||||
|                             "version": "1.0.0", | ||||
|                             "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", | ||||
|                             "resolved": "http://registry.npm.taobao.org/entities/download/entities-1.0.0.tgz", | ||||
|                             "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", | ||||
|                             "dev": true | ||||
|                         } | ||||
|  | @ -17085,13 +17070,13 @@ | |||
|                 }, | ||||
|                 "isarray": { | ||||
|                     "version": "0.0.1", | ||||
|                     "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", | ||||
|                     "resolved": "http://registry.npm.taobao.org/isarray/download/isarray-0.0.1.tgz", | ||||
|                     "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", | ||||
|                     "dev": true | ||||
|                 }, | ||||
|                 "loader-utils": { | ||||
|                     "version": "0.2.17", | ||||
|                     "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", | ||||
|                     "resolved": "http://registry.npm.taobao.org/loader-utils/download/loader-utils-0.2.17.tgz", | ||||
|                     "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", | ||||
|                     "dev": true, | ||||
|                     "requires": { | ||||
|  | @ -17103,7 +17088,7 @@ | |||
|                 }, | ||||
|                 "readable-stream": { | ||||
|                     "version": "1.1.14", | ||||
|                     "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", | ||||
|                     "resolved": "http://registry.npm.taobao.org/readable-stream/download/readable-stream-1.1.14.tgz", | ||||
|                     "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", | ||||
|                     "dev": true, | ||||
|                     "requires": { | ||||
|  | @ -17115,7 +17100,7 @@ | |||
|                 }, | ||||
|                 "string_decoder": { | ||||
|                     "version": "0.10.31", | ||||
|                     "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", | ||||
|                     "resolved": "http://registry.npm.taobao.org/string_decoder/download/string_decoder-0.10.31.tgz", | ||||
|                     "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", | ||||
|                     "dev": true | ||||
|                 } | ||||
|  | @ -17319,7 +17304,7 @@ | |||
|         }, | ||||
|         "webidl-conversions": { | ||||
|             "version": "2.0.1", | ||||
|             "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-2.0.1.tgz", | ||||
|             "resolved": "http://registry.npm.taobao.org/webidl-conversions/download/webidl-conversions-2.0.1.tgz", | ||||
|             "integrity": "sha1-O/glj30xjHRDw28uFpQCoaZwNQY=", | ||||
|             "dev": true, | ||||
|             "optional": true | ||||
|  | @ -18038,7 +18023,7 @@ | |||
|         }, | ||||
|         "whatwg-url-compat": { | ||||
|             "version": "0.6.5", | ||||
|             "resolved": "https://registry.npmjs.org/whatwg-url-compat/-/whatwg-url-compat-0.6.5.tgz", | ||||
|             "resolved": "http://registry.npm.taobao.org/whatwg-url-compat/download/whatwg-url-compat-0.6.5.tgz", | ||||
|             "integrity": "sha1-AImBEa9om7CXVBzVpFymyHmERb8=", | ||||
|             "dev": true, | ||||
|             "optional": true, | ||||
|  | @ -18168,7 +18153,7 @@ | |||
|         }, | ||||
|         "xml-name-validator": { | ||||
|             "version": "2.0.1", | ||||
|             "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", | ||||
|             "resolved": "http://registry.npm.taobao.org/xml-name-validator/download/xml-name-validator-2.0.1.tgz", | ||||
|             "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", | ||||
|             "dev": true, | ||||
|             "optional": true | ||||
|  | @ -18250,4 +18235,4 @@ | |||
|             "dev": true | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 tjz
						tjz