This commit is contained in:
izbz wh 2019-05-22 14:20:04 +08:00
commit 2a088819f3
30 changed files with 20563 additions and 5137 deletions

View File

@ -1,5 +1,20 @@
<a name="2.0.17"></a> <a name="2.0.20"></a>
## [2.0.17](https://github.com/tinper-bee/bee-table/compare/v2.0.16...v2.0.17) (2019-05-10) ## [2.0.20](https://github.com/tinper-bee/bee-table/compare/v2.0.19...v2.0.20) (2019-05-21)
<a name="2.0.19"></a>
## [2.0.19](https://github.com/tinper-bee/bee-table/compare/v2.0.18...v2.0.19) (2019-05-15)
### Bug Fixes
* **bee-table:** ie11下removeEventListener报错bug ([59d03c3](https://github.com/tinper-bee/bee-table/commit/59d03c3))
<a name="2.0.18"></a>
## [2.0.18](https://github.com/tinper-bee/bee-table/compare/v2.0.16...v2.0.18) (2019-05-13)
### Bug Fixes ### Bug Fixes

View File

@ -16,10 +16,6 @@ var _shallowequal = require('shallowequal');
var _shallowequal2 = _interopRequireDefault(_shallowequal); var _shallowequal2 = _interopRequireDefault(_shallowequal);
var _beeIcon = require('bee-icon');
var _beeIcon2 = _interopRequireDefault(_beeIcon);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; } function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
@ -66,10 +62,8 @@ var ExpandIcon = function (_Component) {
if (expandable && !isHiddenExpandIcon) { if (expandable && !isHiddenExpandIcon) {
var expandClassName = expanded ? 'expanded' : 'collapsed'; var expandClassName = expanded ? 'expanded' : 'collapsed';
var currentIcon = _react2["default"].createElement(_beeIcon2["default"], { var currentIcon = _react2["default"].createElement('span', {
className: clsPrefix + '-expand-icon ' + clsPrefix + '-' + expandClassName, className: clsPrefix + '-expand-icon ' + clsPrefix + '-' + expandClassName
type: expanded ? 'uf-triangle-down' : 'uf-triangle-right'
}); });
if (expanded && expandedIcon) { if (expanded && expandedIcon) {
currentIcon = expandedIcon; currentIcon = expandedIcon;

View File

@ -328,6 +328,12 @@
visibility: hidden; } visibility: hidden; }
.u-table-row-spaced:after, .u-table-expanded-row-spaced:after { .u-table-row-spaced:after, .u-table-expanded-row-spaced:after {
content: "."; } content: "."; }
.u-table-row-expanded:after, .u-table-expanded-row-expanded:after {
content: "\e639";
font-family: "uf" !important; }
.u-table-row-collapsed:after, .u-table-expanded-row-collapsed:after {
content: "\e61c";
font-family: "uf" !important; }
.u-table-row.selected { .u-table-row.selected {
background: #FFF7E7; } background: #FFF7E7; }
.u-table tr.u-table-expanded-row { .u-table tr.u-table-expanded-row {

View File

@ -52,6 +52,12 @@ var _beeIcon = require('bee-icon');
var _beeIcon2 = _interopRequireDefault(_beeIcon); var _beeIcon2 = _interopRequireDefault(_beeIcon);
var _i18n = require('./lib/i18n');
var _i18n2 = _interopRequireDefault(_i18n);
var _tool = require('bee-locale/build/tool');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; } function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
@ -141,18 +147,7 @@ var defaultProps = {
getBodyWrapper: function getBodyWrapper(body) { getBodyWrapper: function getBodyWrapper(body) {
return body; return body;
}, },
emptyText: function emptyText() { // emptyText: () => <div><Icon type="uf-nodata" className="table-nodata"></Icon><span>{locale["no_data"]}</span></div>,
return _react2["default"].createElement(
'div',
null,
_react2["default"].createElement(_beeIcon2["default"], { type: 'uf-nodata', className: 'table-nodata' }),
_react2["default"].createElement(
'span',
null,
'\u6682\u65E0\u6570\u636E'
)
);
},
columns: [], columns: [],
minColumnWidth: 80, minColumnWidth: 80,
locale: {}, locale: {},
@ -1179,10 +1174,26 @@ var Table = function (_Component) {
Table.prototype.getEmptyText = function getEmptyText() { Table.prototype.getEmptyText = function getEmptyText() {
var _props7 = this.props, var _props7 = this.props,
emptyText = _props7.emptyText, defaultEmptyText = _props7.emptyText,
clsPrefix = _props7.clsPrefix, clsPrefix = _props7.clsPrefix,
data = _props7.data; data = _props7.data;
var locale = (0, _tool.getComponentLocale)(this.props, this.context, 'Table', function () {
return _i18n2["default"];
});
var emptyText = defaultEmptyText !== undefined ? defaultEmptyText() : function () {
return _react2["default"].createElement(
'div',
null,
_react2["default"].createElement(_beeIcon2["default"], { type: 'uf-nodata', className: 'table-nodata' }),
_react2["default"].createElement(
'span',
null,
locale["no_data"]
)
);
};
return !data.length ? _react2["default"].createElement( return !data.length ? _react2["default"].createElement(
'div', 'div',
{ className: clsPrefix + '-placeholder' }, { className: clsPrefix + '-placeholder' },
@ -1481,6 +1492,9 @@ var Table = function (_Component) {
Table.propTypes = propTypes; Table.propTypes = propTypes;
Table.defaultProps = defaultProps; Table.defaultProps = defaultProps;
Table.contextTypes = {
beeLocale: _propTypes2["default"].object
};
exports["default"] = Table; exports["default"] = Table;
module.exports = exports['default']; module.exports = exports['default'];

View File

@ -15,6 +15,7 @@ module.exports = {
'less_than_equal_to': '小于等于', 'less_than_equal_to': '小于等于',
'be_equal_to': '等于', 'be_equal_to': '等于',
'not_equal_to': '不等于', 'not_equal_to': '不等于',
"no_data": '暂无数据',
'en-us': { 'en-us': {
'resetSettings': 'reset settings', 'resetSettings': 'reset settings',
'include': 'include', 'include': 'include',
@ -28,7 +29,8 @@ module.exports = {
'less_than': 'less than', 'less_than': 'less than',
'less_than_equal_to': 'less than equal to', 'less_than_equal_to': 'less than equal to',
'be_equal_to': 'be equal to', 'be_equal_to': 'be equal to',
'not_equal_to': 'not equal to' 'not_equal_to': 'not equal to',
"no_data": 'no data'
}, },
'zh-tw': { 'zh-tw': {
'resetSettings': '還原設置', 'resetSettings': '還原設置',
@ -43,6 +45,7 @@ module.exports = {
'less_than': '小於', 'less_than': '小於',
'less_than_equal to': '小於等於', 'less_than_equal to': '小於等於',
'be_equal_to': '等於', 'be_equal_to': '等於',
'not_equal_to': '不等於' 'not_equal_to': '不等於',
"no_data": '暫無數據'
} }
}; };

124
build/lib/singleSelect.js Normal file
View File

@ -0,0 +1,124 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
exports["default"] = singleSelect;
var _react = require("react");
var _react2 = _interopRequireDefault(_react);
var _util = require("./util");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : _defaults(subClass, superClass); }
/**
* 参数: 单选表头
* @param {*} Table
* @param {*} Radio
*/
function singleSelect(Table, Radio) {
var _class, _temp;
return _temp = _class = function (_Component) {
_inherits(SingleSelect, _Component);
function SingleSelect(props) {
_classCallCheck(this, SingleSelect);
var _this = _possibleConstructorReturn(this, _Component.call(this, props));
_this.onRadioChange = function (value, record, index) {
_this.setState({ selectedRowIndex: index });
_this.props.getSelectedDataFunc(record, index);
};
_this.getDefaultColumns = function (columns) {
var selectedRowIndex = _this.state.selectedRowIndex;
var _defaultColumns = [{
title: '',
key: "radio",
dataIndex: "radio",
fixed: "left",
width: 49,
render: function render(text, record, index) {
return _react2["default"].createElement(
Radio.RadioGroup,
{
className: "table-radio",
name: "table-radio",
selectedValue: selectedRowIndex,
onChange: function onChange(value) {
return _this.onRadioChange(value, record, index);
},
style: { width: '16px', height: '16px', display: 'block', marginLeft: '4px' } },
_react2["default"].createElement(Radio, { value: index })
);
}
}];
return _defaultColumns.concat(columns);
};
_this.state = {
data: (0, _util.ObjectAssign)(props.data),
selectedRowIndex: props.selectedRowIndex
};
return _this;
}
SingleSelect.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
if ('data' in nextProps) {
this.setState({
data: (0, _util.ObjectAssign)(nextProps.data)
});
}
if ('selectedRowIndex' in nextProps) {
this.setState({
selectedRowIndex: nextProps.selectedRowIndex
});
}
};
/**
* 判断是否是数组
* @param {*} o
*/
SingleSelect.prototype.isArray = function isArray(o) {
return Object.prototype.toString.call(o) == '[object Array]';
};
SingleSelect.prototype.render = function render() {
var columns = this.props.columns;
var data = this.state.data;
return _react2["default"].createElement(Table, _extends({}, this.props, {
columns: this.getDefaultColumns(columns),
data: data,
height: 40 }));
};
return SingleSelect;
}(_react.Component), _class.defaultProps = {
prefixCls: "u-table-single-select",
getSelectedDataFunc: function getSelectedDataFunc() {},
selectedRowIndex: ''
}, _temp;
}
module.exports = exports["default"];

View File

@ -230,11 +230,12 @@ function addHandler(element, type, handler) {
} }
function removeHandler(element, type, handler) { function removeHandler(element, type, handler) {
if (element.removeEventListener) { if (element && element.removeEventListener) {
//element&& ie11报错兼容
element.removeEventListener(type, handler, false); element.removeEventListener(type, handler, false);
} else if (element.detachEvent) { } else if (element && element.detachEvent) {
element.detachEvent("on" + type, handler); element.detachEvent("on" + type, handler);
} else { } else if (element) {
element["on" + type] = null; element["on" + type] = null;
} }
} }
@ -278,11 +279,12 @@ var EventUtil = exports.EventUtil = {
}, },
removeHandler: function removeHandler(element, type, handler) { removeHandler: function removeHandler(element, type, handler) {
if (element.removeEventListener) { //element&& ie11报错兼容
if (element && element.removeEventListener) {
element.removeEventListener(type, handler, false); element.removeEventListener(type, handler, false);
} else if (element.detachEvent) { } else if (element && element.detachEvent) {
element.detachEvent('on' + type, handler); element.detachEvent('on' + type, handler);
} else { } else if (element) {
element['on' + type] = null; element['on' + type] = null;
} }
} }

View File

@ -509,15 +509,15 @@ class Demo0505 extends Component {
<div className="toolbar-btns"> <div className="toolbar-btns">
{isEditingAll ? ( {isEditingAll ? (
<React.Fragment> <React.Fragment>
<Button colors="primary" onClick={this.commitChange}>
确认
</Button>
<Button <Button
bordered bordered
onClick={this.abortEdit} onClick={this.abortEdit}
> >
取消 取消
</Button> </Button>
<Button colors="primary" onClick={this.commitChange}>
确认
</Button>
</React.Fragment> </React.Fragment>
) : ( ) : (
<Button colors="secondary" onClick={this.edit}> <Button colors="secondary" onClick={this.edit}>

View File

@ -62,6 +62,7 @@ class Demo22 extends Component {
columns={columns} columns={columns}
data={data} data={data}
bordered bordered
dragborder={true}
draggable={true} draggable={true}
onDrop ={(event,data,columns)=>{ onDrop ={(event,data,columns)=>{
console.log("--拖拽交换列后触发事件"); console.log("--拖拽交换列后触发事件");

79
demo/demolist/Demo1302.js Normal file
View File

@ -0,0 +1,79 @@
/**
*
* @title 单选功能
* @parent 行操作-选择
* @description 表格支持单选行操作可自定义选中行背景色getSelectedDataFunc方法是选中行的回调函数
* Demo1302
*/
import React, { Component } from "react";
import { Radio } from "tinper-bee";
import Table from "../../src";
import singleSelect from "../../src/lib/singleSelect.js";
const columns = [
{ title: "员工编号", dataIndex: "a", key: "a", width: 300 },
{ title: "员工姓名", dataIndex: "b", key: "b", width: 500 },
{ title: "性别", dataIndex: "c", key: "c", width: 500 },
{ title: "部门", dataIndex: "d", key: "d", width: 200 }
];
const data = [
{ a: "ASVAL_201903280005", b: "小张", c: "男", d: "财务二科", key: "1" },
{ a: "ASVAL_201903200004", b: "小明", c: "男", d: "财务一科", key: "2" },
{ a: "ASVAL_201903120002", b: "小红", c: "女", d: "财务一科", key: "3" },
{ a: "ASVAL_201903280010", b: "小王", c: "女", d: "财务二科", key: "4" },
{ a: "ASVAL_201903200021", b: "小李", c: "男", d: "财务一科", key: "5" }
];
//拼接成复杂功能的table组件不能在render中定义需要像此例子声明在组件的外侧不然操作state会导致功能出现异常
let SingleSelectTable = singleSelect(Table, Radio);
class Demo1302 extends Component {
constructor(props){
super(props);
this.state = {
data: data,
selectedRowIndex: 0,
}
}
/**
*@param selected 当前选中的行数据(当前操作行数据)
*@param index 当前操作行索引
* @memberof Demo12
*/
getSelectedDataFunc = (record,index) => {
console.log("record", record, "index",index);
this.setState({
selectedRowIndex:index
})
};
render() {
let {selectedRowIndex} = this.state;
return (
<SingleSelectTable
className="demo1302"
bordered
columns={columns}
data={data}
selectedRowIndex={selectedRowIndex}
rowClassName={(record,index,indent)=>{
if (index === selectedRowIndex) {
return 'selected';
} else {
return '';
}
}}
getSelectedDataFunc={this.getSelectedDataFunc}
/>
);
}
}
export default Demo1302;

View File

@ -1,72 +0,0 @@
/**
*
* @title 单选功能
* @parent 行操作-选择
* @description 表格支持单选行操作可自定义选中行背景色
* Demo1304
*/
import React, { Component } from "react";
import {Button,Tooltip,Radio} from "tinper-bee";
import Table from "../../src";
const data = [
{ check: "ASVAL_201903280005",a: "ASVAL_201903280005", b: "小张", c: "男", d: "财务二科", key: "1" },
{ check: "ASVAL_201903200004",a: "ASVAL_201903200004", b: "小明", c: "男", d: "财务一科", key: "2" },
{ check: "ASVAL_201903120002",a: "ASVAL_201903120002", b: "小红", c: "女", d: "财务一科", key: "3" }
];
class Demo1304 extends Component {
constructor(props){
super(props);
this.state = {
data: data,
selectedRowIndex: 0,
selectedValue:"ASVAL_201903280005"
}
}
render() {
let {selectedValue} = this.state;
let columns = [
{ title: "单选", dataIndex: "check", key: "check", width: 49, textAlign:'center',render(text, record, index){
return(
<Radio.RadioGroup name="fruits" selectedValue={selectedValue}>
<Radio value={record.check} />
</Radio.RadioGroup>)
}},
{ title: "员工编号", dataIndex: "a", key: "a", width: 300},
{ title: "员工姓名", dataIndex: "b", key: "b", width: 500 },
{ title: "性别", dataIndex: "c", key: "c", width: 500 },
{ title: "部门", dataIndex: "d", key: "d", width: 200 }
];
return (
<Table
className="demo1304"
columns={columns}
data={data}
bordered
height={40}
headerheight={40}
rowClassName={(record,index,indent)=>{
if (this.state.selectedRowIndex == index) {
return 'selected';
} else {
return '';
}
}}
onRowClick={(record,index,indent)=>{
this.setState({
selectedRowIndex: index,
selectedValue:record.check
});
}}
/>
);
}
}
export default Demo1304;

View File

@ -1,8 +0,0 @@
.demo1304{
.u-table-tbody .u-radio-group{
width: 16px;
height: 16px;
display: block;
margin-left: 8px;
}
}

View File

@ -28,7 +28,7 @@ const columns = [
<Tooltip inverse overlay={text}> <Tooltip inverse overlay={text}>
<span tootip={text} style={{ <span tootip={text} style={{
display: "block", display: "block",
width: "80px", width: "40px",
textOverflow: "ellipsis", textOverflow: "ellipsis",
overflow: "hidden", overflow: "hidden",
whiteSpace: "nowrap", whiteSpace: "nowrap",

View File

@ -2,7 +2,7 @@
* *
* @title 嵌套子表格滚动加载 * @title 嵌套子表格滚动加载
* @parent 无限滚动 Infinite-scroll * @parent 无限滚动 Infinite-scroll
* @description 通过expandedRowRender参数来实现子表格 * @description 通过expandedRowRender参数来实现子表格注意事项传入的表格数据必须有 key 值作为唯一标识否则会导致表格的收起展开功能出现问题
* demo1402 * demo1402
*/ */

View File

@ -32,7 +32,7 @@ const columns = [
<Tooltip inverse overlay={text}> <Tooltip inverse overlay={text}>
<span tootip={text} style={{ <span tootip={text} style={{
display: "block", display: "block",
width: "80px", width: "40px",
textOverflow: "ellipsis", textOverflow: "ellipsis",
overflow: "hidden", overflow: "hidden",
whiteSpace: "nowrap", whiteSpace: "nowrap",

View File

@ -27,7 +27,7 @@ const columns = [
<Tooltip inverse overlay={text}> <Tooltip inverse overlay={text}>
<span tootip={text} style={{ <span tootip={text} style={{
display: "block", display: "block",
width: "80px", width: "40px",
textOverflow: "ellipsis", textOverflow: "ellipsis",
overflow: "hidden", overflow: "hidden",
whiteSpace: "nowrap", whiteSpace: "nowrap",
@ -68,8 +68,8 @@ class Demo34 extends Component {
selectedRowIndex: 0 selectedRowIndex: 0
} }
} }
onExpandedRowsChange = (params)=>{ onExpandedRowsChange = (expandedRowKeys)=>{
console.log(params); console.log('expandedRowKeys',expandedRowKeys);
} }
onExpand = (expandKeys)=>{ onExpand = (expandKeys)=>{
console.log('expand---'+expandKeys); console.log('expand---'+expandKeys);
@ -85,6 +85,7 @@ class Demo34 extends Component {
onRowClick={(record, index, indent) => { onRowClick={(record, index, indent) => {
console.log('currentIndex--'+index); console.log('currentIndex--'+index);
}} }}
onExpandedRowsChange={this.onExpandedRowsChange}
/> />

File diff suppressed because one or more lines are too long

12
dist/demo.css vendored
View File

@ -317,6 +317,12 @@
visibility: hidden; } visibility: hidden; }
.u-table-row-spaced:after, .u-table-expanded-row-spaced:after { .u-table-row-spaced:after, .u-table-expanded-row-spaced:after {
content: "."; } content: "."; }
.u-table-row-expanded:after, .u-table-expanded-row-expanded:after {
content: "\e639";
font-family: "uf" !important; }
.u-table-row-collapsed:after, .u-table-expanded-row-collapsed:after {
content: "\e61c";
font-family: "uf" !important; }
.u-table-row.selected { .u-table-row.selected {
background: #FFF7E7; } background: #FFF7E7; }
.u-table tr.u-table-expanded-row { .u-table tr.u-table-expanded-row {
@ -1046,12 +1052,6 @@ th .drop-menu .uf {
th:hover .uf { th:hover .uf {
visibility: visible; } visibility: visible; }
.demo1304 .u-table-tbody .u-radio-group {
width: 16px;
height: 16px;
display: block;
margin-left: 8px; }
.demo8 .u-table { .demo8 .u-table {
margin-bottom: 11px; } margin-bottom: 11px; }

2
dist/demo.css.map vendored

File diff suppressed because one or more lines are too long

25048
dist/demo.js vendored

File diff suppressed because one or more lines are too long

6
dist/demo.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -32,65 +32,69 @@ import 'bee-table/build/Table.css';
## API ## API
### Table ### Table props
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
| :--------------------- | :--------------------------------------- | :------------------------------------- | :-------------- | | :--------------------- | :--------------------------------------- | :------------------------------------- | :-------------- |
| data | 传入的表格数据key值必需否则会导致部分功能出现问题。建议使用唯一的值如id | array | [] | | data | 传入的表格数据key值必需否则会导致部分功能出现问题。建议使用唯一的值如id | array | [] |
| bordered | 是否展示外边框和列边框 | boolean | false |
| columns | 列的配置表,具体配置见下表 | array | - | | columns | 列的配置表,具体配置见下表 | array | - |
| bordered | 是否展示外边框和列边框 | boolean | false |
| defaultExpandAllRows | 默认是否展开所有行 | bool | false | | defaultExpandAllRows | 默认是否展开所有行 | bool | false |
| expandedRowKeys | 展开的行,控制属性 | array | - |
| defaultExpandedRowKeys | 初始扩展行键 | array | [] | | defaultExpandedRowKeys | 初始扩展行键 | array | [] |
| bodyStyle | 添加到tablebody上的style | object | {} | | rowRef | 获取行的ref | Function(record, index, indent):string | () => null |
| style | 添加到table上的style | object | {} |
| rowKey | 如果rowKey是字符串`record [rowKey]`将被用作键。如果rowKey是function`rowKeyrecord, index`的返回值将被用作键。 | string or Function(record, index):string | 'key' | | rowKey | 如果rowKey是字符串`record [rowKey]`将被用作键。如果rowKey是function`rowKeyrecord, index`的返回值将被用作键。 | string or Function(record, index):string | 'key' |
| rowClassName | 获取行的classname | Function(record, index, indent):string | () => '' | | expandedRowKeys | 展开的行,控制属性 | array | - |
| expandedRowClassName | 获取展开行的className | Function(recode, index, indent):string | () => '' | | rowClassName | 获取行的classname | Function(record, index, indent):string | () => '' |
| onExpand | 展开行时的钩子函数 | Function(expanded, record) | () => '' | | expandedRowClassName | 获取展开行的className | Function(recode, index, indent):string | () => '' |
| onExpandedRowsChange | 函数在扩展行更改时调用 | Function(expandedRows) | () => '' |
| indentSize | indentSize为每个级别的data.i.children更好地使用column.width指定 | number | 15 | | indentSize | indentSize为每个级别的data.i.children更好地使用column.width指定 | number | 15 |
| onRowClick | 行的点击事件钩子函数 | Function(record, index, event) | () => '' |
| onRowDoubleClick | 行的双击事件钩子函数 | Function(record, index, event) | () => '' |
| expandIconAsCell | 是否将expandIcon作为单元格 | bool | false | | expandIconAsCell | 是否将expandIcon作为单元格 | bool | false |
| expandIconColumnIndex | expandIcon的索引当expandIconAsCell为false时将插入哪个列 | number | 0 | | expandIconColumnIndex | expandIcon的索引当expandIconAsCell为false时将插入哪个列 | number | 0 |
| expandedRowRender | 额外的展开行 | Function(record, index, indent):node | - |
| haveExpandIcon | 控制是否显示行展开icon.**注该参数只有在和expandedRowRender同时使用才生效** | Function(record, index):bool | () =>false |
|expandedIcon|嵌套表格场景中展开子表时的展开图标|||
|collapsedIcon|嵌套表格场景中关闭子表时的关闭图标|||
| expandIconAsCell | 展开按钮是否单独作为一个单元格 | bool | false |
| expandRowByClick | 设置展开行是否通过点击行触发,此参数需要与上面参数搭配使用(默认是通过点击行前面的加号展开行 | bool | false |
| rowDraggAble | 是否增加行交换顺序功能 | boolean| false |
| showHeader | 是否显示表头 | bool | true | | showHeader | 是否显示表头 | bool | true |
| title | 表格标题 | Function | - | | title | 表格标题 | Function | - |
| footer | 表格尾部 | Function | - | | footer | 表格尾部 | Function | - |
| emptyText | 无数据时显示的内容 | Function | () => 'No Data' | | emptyText | 无数据时显示的内容 | Function | () => 'No Data' |
| scroll | 横向或纵向支持滚动,也可用于指定滚动区域的宽高度 | `{ x: number / 百分比 , y: number }` | {} |
| rowRef | 获取行的ref | Function(record, index, indent):string | () => null |
| getBodyWrapper | 添加对table body的包装 | Function(body) | body => body |
| expandedRowRender | 额外的展开行 | Function(record, index, indent):node | - |
| expandIconAsCell | 展开按钮是否单独作为一个单元格 | bool | false |
| expandRowByClick | 设置展开行是否通过点击行触发,此参数需要与上面参数搭配使用(默认是通过点击行前面的加号展开行 | bool | false |
| footerScroll | 表尾和body是否公用同一个横向滚动条。 如果footer中也是一个table组件并且也具有滚动条那么也需要加入footerScroll参数内层表格的footerScroll设置成false。 | bool | false |
| loading | 表格是否加载中 | bool|object(详情可以参考上面示例) | false | | loading | 表格是否加载中 | bool|object(详情可以参考上面示例) | false |
| haveExpandIcon | 控制是否显示行展开icon.**注该参数只有在和expandedRowRender同时使用才生效** | Function(record, index):bool | () =>false | | getBodyWrapper | 添加对table body的包装 | Function(body) | body => body |
| bodyStyle | 添加到tablebody上的style | object | {} |
| style | 添加到table上的style | object | {} |
| scroll | 横向或纵向支持滚动,也可用于指定滚动区域的宽高度 | `{ x: number / 百分比 , y: number }` | {} |
| headerScroll | 表头下是否显示滚动条 | bool| false |
| footerScroll | 表尾和body是否公用同一个横向滚动条。 如果footer中也是一个table组件并且也具有滚动条那么也需要加入footerScroll参数内层表格的footerScroll设置成false。 | bool | false |
| resetScroll | 将表格横向滚动条位置还原 | bool| false
| filterable | 是否开启根据条件来过滤数据 | bool | false | filterable | 是否开启根据条件来过滤数据 | bool | false
| filterDelay | 触发过滤输入的时候的ms延迟时间 | number | 300 | filterDelay | 触发过滤输入的时候的ms延迟时间 | number | 300
| onFilterChange | 触发过滤输入操作以及下拉条件的回调 | function | (field,value,condition) => ()
| onFilterClear | 清除过滤条件的回调函数,回调参数为清空的字段 | function | (field) => ()
| headerScroll | 表头下是否显示滚动条 | bool| false
| sort | 排序的属性 | object| { mode:'single'//单列排序, backSource:false //默认是前端排序值为true为后端排序 } mode:multiple-多列排序 | sort | 排序的属性 | object| { mode:'single'//单列排序, backSource:false //默认是前端排序值为true为后端排序 } mode:multiple-多列排序
| syncHover | 是否同步Hover状态到左侧Checkbox关闭此功能有助于提升性能 | bool| true | syncHover | 是否同步Hover状态到左侧Checkbox关闭此功能有助于提升性能 | bool| true
| loadBuffer | 使用BigData高阶组件实现大数据加载时上下加载的缓存 | number| 5 | loadBuffer | 使用BigData高阶组件实现大数据加载时上下加载的缓存 | number| 5
| resetScroll | 将表格横向滚动条位置还原 | bool| false
| hoverContent | hover某行时动态渲染行菜单元素此方法需返回行菜单元素的内容 | Function| | hoverContent | hover某行时动态渲染行菜单元素此方法需返回行菜单元素的内容 | Function|
| onRowHover | 行hover时的回调函数 | Function|
| heightConsistent | 当固定列内容高度超出非固定列时内容互错行当此属性为true会将高度同步当行过多时会有性能影响所以建议非固定高度如果过高时超出内容可以显示成省略号 | bool|false | heightConsistent | 当固定列内容高度超出非固定列时内容互错行当此属性为true会将高度同步当行过多时会有性能影响所以建议非固定高度如果过高时超出内容可以显示成省略号 | bool|false
| height | 自定义表格行高 | number | - | | height | 自定义表格行高 | number | - |
| headerHeight | 自定义表头行高 | number | - | | headerHeight | 自定义表头行高 | number | - |
| size | 表格大小 | `sm / md / lg` | 'md' |
| headerDisplayInRow | 设置表头的内容显示一行,超出显示省略号 | bool | | headerDisplayInRow | 设置表头的内容显示一行,超出显示省略号 | bool |
| bodyDisplayInRow | 设置表体的内容显示一行,超出显示省略号 | bool | | bodyDisplayInRow | 设置表体的内容显示一行,超出显示省略号 | bool |
| rowDraggAble | 是否增加行交换顺序功能 | boolean| false | size | 表格大小 | `sm / md / lg` | 'md' |
|expandedIcon|嵌套表格场景中展开子表时的展开图标|||
|collapsedIcon|嵌套表格场景中关闭子表时的关闭图标|||
> 快捷键部分参考示例 (快捷键在table中的简单使用应用) > 快捷键部分参考示例 (快捷键在table中的简单使用应用)
*注意: data参数中的key值必需否则会导致部分功能出现问题建议使用唯一的值如id* *注意: data参数中的key值必需否则会导致部分功能出现问题建议使用唯一的值如id*
### Table events
| 事件名 | 说明 | 类型 | 返回值 |
| :--- | :--- | :--- | :--- |
| onExpand | 展开行时的钩子函数 | Function(expanded, record) | `expanded` : 当前的状态<br>`record` : 当前行的数据 |
| onExpandedRowsChange | 函数在扩展行更改时调用 | Function(expandedRowKeys) | `expandedRowKeys` : 展开行的keys数组 |
| onRowClick | 行的点击事件钩子函数 | Function(record, index, event) | `record` : 当前行的数据<br> `index` : 当前行的index<br> `event` : 事件对象 |
| onRowDoubleClick | 行的双击事件钩子函数 | Function(record, index, event) | `record` : 当前行的数据<br> `index` : 当前行的index<br> `event` : 事件对象 |
| onFilterChange | 触发过滤输入操作以及下拉条件的回调 | function(field,value,condition) | `field` : 字段名称 <br> `value` : 字段值 <br> `condition` : 判断条件 |
| onFilterClear | 清除过滤条件的回调函数,回调参数为清空的字段 | function(field) | `field` : 字段名称 |
| onRowHover | 行hover时的回调函数 | function(index,record) | `index` : 当前行的index<br> `record` : 当前行的数据 |
### Column ### Column
@ -122,9 +126,9 @@ import 'bee-table/build/Table.css';
### 高阶函数 ### 高阶函数
Table内部封装了个高阶组件,接收基础 Table 组件作为输入,输出一个新的复杂 Table 组件。高阶组件让代码更具有复用性、逻辑性与抽象特征。 Table内部封装了个高阶组件,接收基础 Table 组件作为输入,输出一个新的复杂 Table 组件。高阶组件让代码更具有复用性、逻辑性与抽象特征。
![image](https://user-images.githubusercontent.com/33412781/57187761-88701d00-6f26-11e9-9b31-d57c85ae3e23.png) ![image](https://user-images.githubusercontent.com/33412781/58004582-29a9c680-7b16-11e9-8608-192bde91a9f5.png)
> 注不要在render方法内部使用高阶组件。这样不仅会有性能问题 重新挂载一个组件还会导致这个组件的状态和他所有的子节点的状态丢失。 > 注不要在render方法内部使用高阶组件。这样不仅会有性能问题 重新挂载一个组件还会导致这个组件的状态和他所有的子节点的状态丢失。
@ -134,6 +138,28 @@ Table内部封装了六个高阶组件接收基础 Table 组件作为输入
import multiSelect from "tinper-bee/lib/multiSelect.js"; import multiSelect from "tinper-bee/lib/multiSelect.js";
``` ```
### singleSelect 单选功能
#### 如何使用
```js
import singleSelect from "tinper-bee/lib/singleSelect.js";
import { Table, Radio } from 'tinper-bee';
const SingleSelectTable = singleSelect(Table, Radio);
```
#### API
Table 组件参数:
| 参数 | 说明 | 类型 | 默认值 |
| ------ | ---------- | -------- | ---- |
| getSelectedDataFunc | 返回当前选中的数据数组 | Function | 无 |
| selectedRowIndex | 指定当前选中数据的 index | number | 无 |
### multiSelect 多选功能 ### multiSelect 多选功能
#### 如何使用 #### 如何使用

View File

@ -78,9 +78,11 @@
} }
}, },
"API": { "API": {
"Table": "", "Table props": "",
"Table events": "",
"Column": "", "Column": "",
"高阶函数": { "高阶函数": {
"singleSelect 单选功能": "",
"multiSelect 多选功能": "", "multiSelect 多选功能": "",
"sort 排序功能": "", "sort 排序功能": "",
"sum 合计功能": "", "sum 合计功能": "",

View File

@ -1,6 +1,6 @@
{ {
"name": "bee-table", "name": "bee-table",
"version": "2.0.17", "version": "2.0.20",
"description": "Table ui component for react", "description": "Table ui component for react",
"keywords": [ "keywords": [
"react", "react",
@ -54,7 +54,7 @@
"bee-icon": "latest", "bee-icon": "latest",
"bee-input-number": "^2.0.7", "bee-input-number": "^2.0.7",
"bee-loading": "^1.0.9", "bee-loading": "^1.0.9",
"bee-locale": "0.0.13", "bee-locale": "0.0.14",
"bee-menus": "^2.0.6", "bee-menus": "^2.0.6",
"bee-radio": "^2.0.8", "bee-radio": "^2.0.8",
"bee-select": "^2.0.11", "bee-select": "^2.0.11",
@ -89,8 +89,8 @@
"react": "^16.6.3", "react": "^16.6.3",
"react-addons-test-utils": "^15.5.0", "react-addons-test-utils": "^15.5.0",
"react-dom": "^16.6.3", "react-dom": "^16.6.3",
"ref-tree": "2.0.1-beta.1",
"reqwest": "^2.0.5", "reqwest": "^2.0.5",
"tinper-bee": "latest", "tinper-bee": "latest"
"ref-tree": "2.0.1-beta.1"
} }
} }

View File

@ -1,7 +1,6 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import shallowequal from 'shallowequal'; import shallowequal from 'shallowequal';
import Icon from 'bee-icon';
const propTypes = { const propTypes = {
record: PropTypes.object, record: PropTypes.object,
@ -23,10 +22,8 @@ class ExpandIcon extends Component{
const { expandable, clsPrefix, onExpand, needIndentSpaced, expanded, record, isHiddenExpandIcon,expandedIcon,collapsedIcon } = this.props; const { expandable, clsPrefix, onExpand, needIndentSpaced, expanded, record, isHiddenExpandIcon,expandedIcon,collapsedIcon } = this.props;
if (expandable && !isHiddenExpandIcon) { if (expandable && !isHiddenExpandIcon) {
const expandClassName = expanded ? 'expanded' : 'collapsed'; const expandClassName = expanded ? 'expanded' : 'collapsed';
let currentIcon = <Icon let currentIcon = <span
className={`${clsPrefix}-expand-icon ${clsPrefix}-${expandClassName}`} className={`${clsPrefix}-expand-icon ${clsPrefix}-${expandClassName}`}
type={expanded ? 'uf-triangle-down' : 'uf-triangle-right'}
/>; />;
if(expanded && expandedIcon){ if(expanded && expandedIcon){
currentIcon = expandedIcon; currentIcon = expandedIcon;

View File

@ -11,6 +11,8 @@ import createStore from './createStore';
import Loading from 'bee-loading'; import Loading from 'bee-loading';
import Icon from 'bee-icon'; import Icon from 'bee-icon';
import { Event,EventUtil,closest} from "./utils"; import { Event,EventUtil,closest} from "./utils";
import i18n from "./lib/i18n";
import { getComponentLocale } from "bee-locale/build/tool";
const propTypes = { const propTypes = {
data: PropTypes.array, data: PropTypes.array,
@ -80,7 +82,7 @@ const defaultProps = {
scroll: {}, scroll: {},
rowRef: () => null, rowRef: () => null,
getBodyWrapper: body => body, getBodyWrapper: body => body,
emptyText: () => <div><Icon type="uf-nodata" className="table-nodata"></Icon><span></span></div>, // emptyText: () => <div><Icon type="uf-nodata" className="table-nodata"></Icon><span>{locale["no_data"]}</span></div>,
columns:[], columns:[],
minColumnWidth: 80, minColumnWidth: 80,
locale:{}, locale:{},
@ -1012,7 +1014,10 @@ class Table extends Component {
} }
getEmptyText() { getEmptyText() {
const { emptyText, clsPrefix, data } = this.props; const { emptyText : defaultEmptyText, clsPrefix, data } = this.props;
let locale = getComponentLocale(this.props, this.context, 'Table', () => i18n);
let emptyText = defaultEmptyText !== undefined ? defaultEmptyText() : () => <div><Icon type="uf-nodata" className="table-nodata"></Icon><span>{locale["no_data"]}</span></div>;
return !data.length ? ( return !data.length ? (
<div className={`${clsPrefix}-placeholder`}> <div className={`${clsPrefix}-placeholder`}>
{emptyText()} {emptyText()}
@ -1316,5 +1321,8 @@ class Table extends Component {
Table.propTypes = propTypes; Table.propTypes = propTypes;
Table.defaultProps = defaultProps; Table.defaultProps = defaultProps;
Table.contextTypes = {
beeLocale: PropTypes.object
};
export default Table; export default Table;

View File

@ -295,6 +295,18 @@ $icon-color:#505F79;
&-spaced:after { &-spaced:after {
content: "."; content: ".";
} }
&-expanded {
&:after {
content: "\e639";
font-family: "uf" !important;
}
}
&-collapsed {
&:after {
content: "\e61c";
font-family: "uf" !important;
}
}
} }
&-row{ &-row{
&.selected{ &.selected{

View File

@ -13,6 +13,7 @@ module.exports = {
'less_than_equal_to':'小于等于', 'less_than_equal_to':'小于等于',
'be_equal_to':'等于', 'be_equal_to':'等于',
'not_equal_to':'不等于', 'not_equal_to':'不等于',
"no_data":'暂无数据',
'en-us': { 'en-us': {
'resetSettings': 'reset settings', 'resetSettings': 'reset settings',
'include': 'include', 'include': 'include',
@ -27,6 +28,7 @@ module.exports = {
'less_than_equal_to':'less than equal to', 'less_than_equal_to':'less than equal to',
'be_equal_to':'be equal to', 'be_equal_to':'be equal to',
'not_equal_to':'not equal to', 'not_equal_to':'not equal to',
"no_data":'no data',
}, },
'zh-tw': { 'zh-tw': {
'resetSettings': '還原設置', 'resetSettings': '還原設置',
@ -41,6 +43,7 @@ module.exports = {
'less_than':'小於', 'less_than':'小於',
'less_than_equal to':'小於等於', 'less_than_equal to':'小於等於',
'be_equal_to':'等於', 'be_equal_to':'等於',
'not_equal_to':'不等於' 'not_equal_to':'不等於',
"no_data":'暫無數據',
} }
} }

85
src/lib/singleSelect.js Normal file
View File

@ -0,0 +1,85 @@
import React, { Component } from "react";
import {ObjectAssign} from './util';
/**
* 参数: 单选表头
* @param {*} Table
* @param {*} Radio
*/
export default function singleSelect(Table, Radio) {
return class SingleSelect extends Component {
static defaultProps = {
prefixCls: "u-table-single-select",
getSelectedDataFunc:()=>{},
selectedRowIndex: ''
}
constructor(props) {
super(props);
this.state = {
data:ObjectAssign(props.data),
selectedRowIndex: props.selectedRowIndex
}
}
componentWillReceiveProps(nextProps){
if('data' in nextProps){
this.setState({
data: ObjectAssign(nextProps.data),
})
}
if('selectedRowIndex' in nextProps){
this.setState({
selectedRowIndex: nextProps.selectedRowIndex
})
}
}
/**
* 判断是否是数组
* @param {*} o
*/
isArray(o){
return Object.prototype.toString.call(o)=='[object Array]';
}
onRadioChange = (value, record, index) => {
this.setState({selectedRowIndex: index});
this.props.getSelectedDataFunc(record,index);
}
getDefaultColumns=(columns)=>{
let {selectedRowIndex} = this.state;
let _defaultColumns =[{
title: '',
key: "radio",
dataIndex: "radio",
fixed:"left",
width: 49,
render: (text, record, index) => {
return <Radio.RadioGroup
className="table-radio"
name="table-radio"
selectedValue={selectedRowIndex}
onChange={value => this.onRadioChange(value, record, index)}
style={{width:'16px', height:'16px', display:'block', marginLeft:'4px'}}>
<Radio value={index}/>
</Radio.RadioGroup>
}
}]
return _defaultColumns.concat(columns);
}
render() {
const {columns} = this.props;
const {data} = this.state;
return <Table
{...this.props}
columns={this.getDefaultColumns(columns)}
data={data}
height={40}/>
}
};
}

View File

@ -205,11 +205,11 @@ export function getColChildrenLength(columns,chilrenLen){
} }
function removeHandler(element, type, handler){ function removeHandler(element, type, handler){
if (element.removeEventListener){ if (element&&element.removeEventListener){//element&& ie11报错兼容
element.removeEventListener(type, handler, false); element.removeEventListener(type, handler, false);
} else if (element.detachEvent){ } else if (element&&element.detachEvent){
element.detachEvent("on" + type, handler); element.detachEvent("on" + type, handler);
} else { } else if(element) {
element["on" + type] = null; element["on" + type] = null;
} }
} }
@ -255,15 +255,15 @@ export const EventUtil = {
} }
}, },
removeHandler: function(element,type,handler) { removeHandler: function(element,type,handler) {//element&& ie11报错兼容
if (element.removeEventListener) if (element&&element.removeEventListener)
{ {
element.removeEventListener(type,handler,false); element.removeEventListener(type,handler,false);
} }
else if(element.detachEvent) { else if(element&&element.detachEvent) {
element.detachEvent('on' +type,handler); element.detachEvent('on' +type,handler);
} }
else { else if(element){
element['on'+type] = null; element['on'+type] = null;
} }
} }