fix vc-table

This commit is contained in:
tangjinzhou 2018-03-26 19:05:40 +08:00
parent 0cdf29011d
commit b25dfe8099
7 changed files with 712 additions and 5 deletions

View File

@ -38,11 +38,14 @@ const Dropdown = {
class: `${prefixCls}-trigger`,
disabled,
})
const overlay = $slots.overlay && $slots.overlay[0]
// menu cannot be selectable in dropdown defaultly
const overlay = this.overlay || $slots.overlay && $slots.overlay[0]
// menu cannot be selectable in dropdown defaultly, but multiple type can be selectable
const overlayProps = overlay && getPropsData(overlay)
const selectable = (overlayProps.selectable !== undefined && overlayProps.selectable !== false) || false
const fixedModeOverlay = cloneElement(overlay, {
let selectable = false
if (overlayProps) {
selectable = !!overlayProps.selectable || overlayProps.multiple
}
const fixedModeOverlay = overlay && cloneElement(overlay, {
props: {
mode: 'vertical',
selectable,

View File

@ -0,0 +1,298 @@
@menuPrefixCls: rc-menu;
@font-face {
font-family: 'FontAwesome';
src: url('https://cdn.bootcss.com/font-awesome/4.2.0/fonts/fontawesome-webfont.eot?v=4.2.0');
src: url('https://cdn.bootcss.com/font-awesome/4.2.0/fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'), url('https://cdn.bootcss.com/font-awesome/4.2.0/fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'), url('https://cdn.bootcss.com/font-awesome/4.2.0/fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'), url('https://cdn.bootcss.com/font-awesome/4.2.0/fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');
font-weight: normal;
font-style: normal;
}
.@{menuPrefixCls} {
outline: none;
margin-bottom: 0;
padding-left: 0; // Override default ul/ol
list-style: none;
border: 1px solid #d9d9d9;
box-shadow: 0 0 4px #d9d9d9;
border-radius: 3px;
color: #666;
&-hidden {
display: none;
}
&-collapse {
overflow: hidden;
&-active {
transition: height .3s ease-out;
}
}
&-item-group-list {
margin: 0;
padding: 0;
}
&-item-group-title {
color: #999;
line-height: 1.5;
padding: 8px 10px;
border-bottom: 1px solid #dedede;
}
&-item-active,
&-submenu-active > &-submenu-title {
background-color: #eaf8fe;
}
&-item-selected {
background-color: #eaf8fe;
// fix chrome render bug
transform: translateZ(0);
}
&-submenu-selected {
background-color: #eaf8fe;
}
& > li&-submenu {
padding: 0;
}
&-horizontal&-sub,
&-vertical&-sub,
&-vertical-left&-sub,
&-vertical-right&-sub {
min-width: 160px;
margin-top: 0;
}
&-item, &-submenu-title {
margin: 0;
position: relative;
display: block;
padding: 7px 7px 7px 16px;
white-space: nowrap;
// Disabled state sets text to gray and nukes hover/tab effects
&.@{menuPrefixCls}-item-disabled, &.@{menuPrefixCls}-submenu-disabled {
color: #777 !important;
}
}
& > &-item-divider {
height: 1px;
margin: 1px 0;
overflow: hidden;
padding: 0;
line-height: 0;
background-color: #e5e5e5;
}
&-submenu {
&-popup {
position: absolute;
}
> .@{menuPrefixCls} {
background-color: #fff;
}
}
.@{menuPrefixCls}-submenu-title, .@{menuPrefixCls}-item {
.anticon {
width: 14px;
height: 14px;
margin-right: 8px;
top: -1px;
}
}
&-horizontal {
background-color: #F3F5F7;
border: none;
border-bottom: 1px solid transparent;
border-bottom: 1px solid #d9d9d9;
box-shadow: none;
& > .@{menuPrefixCls}-item, & > .@{menuPrefixCls}-submenu > .@{menuPrefixCls}-submenu-title {
padding: 15px 20px;
}
& > .@{menuPrefixCls}-submenu, & > .@{menuPrefixCls}-item {
float: left;
border-bottom: 2px solid transparent;
&-active {
border-bottom: 2px solid #2db7f5;
background-color: #F3F5F7;
color: #2baee9;
}
}
&:after {
content: "\20";
display: block;
height: 0;
clear: both;
}
}
&-vertical,
&-vertical-left,
&-vertical-right,
&-inline {
padding: 12px 0;
& > .@{menuPrefixCls}-item, & > .@{menuPrefixCls}-submenu > .@{menuPrefixCls}-submenu-title {
padding: 12px 8px 12px 24px;
}
.@{menuPrefixCls}-submenu-arrow {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
vertical-align: baseline;
text-align: center;
text-transform: none;
text-rendering: auto;
position: absolute;
right: 16px;
line-height: 1.5em;
&:before {
content: "\f0da";
}
}
}
&-inline {
.@{menuPrefixCls}-submenu-arrow {
transform: rotate(90deg);
transition: transform .3s;
}
& .@{menuPrefixCls}-submenu-open > .@{menuPrefixCls}-submenu-title {
.@{menuPrefixCls}-submenu-arrow {
transform: rotate(-90deg);
}
}
}
&-vertical&-sub,
&-vertical-left&-sub,
&-vertical-right&-sub {
padding: 0;
}
&-sub&-inline {
padding: 0;
border: none;
border-radius: 0;
box-shadow: none;
& > .@{menuPrefixCls}-item, & > .@{menuPrefixCls}-submenu > .@{menuPrefixCls}-submenu-title {
padding-top: 8px;
padding-bottom: 8px;
padding-right: 0;
}
}
.effect() {
animation-duration: .3s;
animation-fill-mode: both;
transform-origin: 0 0;
}
&-open {
&-slide-up-enter, &-slide-up-appear {
.effect();
opacity: 0;
animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1);
animation-play-state: paused;
}
&-slide-up-leave {
.effect();
opacity: 1;
animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34);
animation-play-state: paused;
}
&-slide-up-enter&-slide-up-enter-active, &-slide-up-appear&-slide-up-appear-active {
animation-name: rcMenuOpenSlideUpIn;
animation-play-state: running;
}
&-slide-up-leave&-slide-up-leave-active {
animation-name: rcMenuOpenSlideUpOut;
animation-play-state: running;
}
@keyframes rcMenuOpenSlideUpIn {
0% {
opacity: 0;
transform-origin: 0% 0%;
transform: scaleY(0);
}
100% {
opacity: 1;
transform-origin: 0% 0%;
transform: scaleY(1);
}
}
@keyframes rcMenuOpenSlideUpOut {
0% {
opacity: 1;
transform-origin: 0% 0%;
transform: scaleY(1);
}
100% {
opacity: 0;
transform-origin: 0% 0%;
transform: scaleY(0);
}
}
&-zoom-enter, &-zoom-appear {
opacity: 0;
.effect();
animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1);
animation-play-state: paused;
}
&-zoom-leave {
.effect();
animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34);
animation-play-state: paused;
}
&-zoom-enter&-zoom-enter-active, &-zoom-appear&-zoom-appear-active {
animation-name: rcMenuOpenZoomIn;
animation-play-state: running;
}
&-zoom-leave&-zoom-leave-active {
animation-name: rcMenuOpenZoomOut;
animation-play-state: running;
}
@keyframes rcMenuOpenZoomIn {
0% {
opacity: 0;
transform: scale(0, 0);
}
100% {
opacity: 1;
transform: scale(1, 1);
}
}
@keyframes rcMenuOpenZoomOut {
0% {
transform: scale(1, 1);
}
100% {
opacity: 0;
transform: scale(0, 0);
}
}
}
}

View File

@ -0,0 +1,108 @@
/* eslint-disable no-console,func-names,react/no-multi-comp */
import Table from '../index'
import '../assets/index.less'
const columns = [
{ title: '手机号', dataIndex: 'a', colSpan: 2, width: 100, key: 'a', render (h, 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 (h, 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 (h, 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 (h, 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 (h, o, row, index) {
const obj = {
children: o,
props: {},
}
if (index === 5) {
obj.props.colSpan = 0
}
return obj
} },
{
title: 'Operations', dataIndex: '', key: 'f',
render (h, 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' },
]
export default {
render () {
return (
<div>
<h2>colSpan & rowSpan</h2>
<Table
columns={columns}
data={data}
class='table'
/>
</div>
)
},
}

View File

@ -0,0 +1,76 @@
/* eslint-disable no-console,func-names,react/no-multi-comp */
import Table from '../index'
import '../assets/index.less'
import BaseMixin from '../../_util/BaseMixin'
const ResizeableTitle = (h, props, children) => {
console.log(props)
const { onResize, width, ...restProps } = props
if (!width) {
return <th {...restProps} >{children}</th>
}
return (
<th {...restProps} width={width}>{children}</th>
)
}
export default {
mixins: [BaseMixin],
data () {
return {
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>
},
},
],
data: [
{ a: '123', key: '1' },
{ a: 'cdd', b: 'edd', key: '2' },
{ a: '1333', c: 'eee', d: 2, key: '3' },
],
components: {
header: {
cell: ResizeableTitle,
},
},
}
},
methods: {
handleResize (index) {
return (e, { size }) => {
this.setState(({ columns }) => {
const nextColumns = [...columns]
nextColumns[index] = {
...nextColumns[index],
width: size.width,
}
return { columns: nextColumns }
})
}
},
},
render () {
const columns = this.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>
)
},
}

View File

@ -0,0 +1,109 @@
/* eslint-disable no-console,func-names,react/no-multi-comp */
import Table from '../index'
import '../assets/index.less'
import Menu from '../../menu'
const Item = Menu.Item
const Divider = Menu.Divider
import DropDown from '../../dropdown'
const data = []
for (let i = 0; i < 10; i++) {
data.push({
key: i,
a: `a${i}`,
b: `b${i}`,
c: `c${i}`,
})
}
export default {
data () {
this.filters = []
return {
visible: false,
}
},
methods: {
handleVisibleChange (visible) {
this.visible = 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.visible = false
},
},
render () {
const menu = (
<Menu
style={{ width: '200px' }}
multiple
selectable
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.visible}
>
<template slot='overlay'>
{menu}
</template>
<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 (
<div>
<h2>use dropdown</h2>
<Table
columns={columns}
data={data}
rowKey={record => record.key}
/>
</div>
)
},
}

View File

@ -0,0 +1,110 @@
/* eslint-disable no-console,func-names,react/no-multi-comp */
import Table from '../index'
import '../assets/index.less'
const tableData = [
{ key: 0, a: '123' },
{ key: 1, a: 'cdd', b: 'edd' },
{ key: 2, a: '1333', c: 'eee', d: 2 },
]
export default {
data () {
return {
data: tableData,
expandedRowKeys: [],
expandIconAsCell: true,
expandRowByClick: false,
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 },
],
}
},
methods: {
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,
})
},
toggleButton () {
if (this.expandedRowKeys.length) {
const closeAll = () => { this.expandedRowKeys = [] }
return <button onClick={closeAll}>Close All</button>
}
const openAll = () => { this.expandedRowKeys = [0, 1, 2] }
return <button onClick={openAll}>Expand All</button>
},
remove (index) {
const data = this.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
return (
<div>
<h2>expandedRowRender</h2>
<div>
{this.toggleButton()}
<span style={{ display: 'inline-block', width: '20px' }} />
<input
type='checkbox'
checked={expandIconAsCell}
onChange={this.onExpandIconAsCellChange}
/>
expandIconAsCell
<span style={{ display: 'inline-block', width: '20px' }} />
<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>
</div>
)
},
}

View File

@ -13,7 +13,7 @@ const TableHeaderRow = {
height: PropTypes.any,
},
name: 'TableHeaderRow',
render () {
render (h) {
const { row, index, height, components, $listeners = {}} = this
const onHeaderRow = $listeners.headerRow
const HeaderRow = components.header.row
@ -40,6 +40,9 @@ const TableHeaderRow = {
...customProps,
key: column.key || column.dataIndex || i,
})
if (typeof HeaderCell === 'function') {
return HeaderCell(h, headerCellProps, children)
}
return (
<HeaderCell
{...headerCellProps}