UNPKG

ukelli-ui

Version:

[![Build Status](https://travis-ci.org/ukelli/ukelli-ui.svg?branch=master)](https://travis-ci.org/ukelli/ukelli-ui) [![install size](https://packagephobia.now.sh/badge?p=ukelli-ui)](https://packagephobia.now.sh/result?p=ukelli-ui)

521 lines (430 loc) 18.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _basicHelper = require("basic-helper"); var _mapperFilter = _interopRequireDefault(require("./mapper-filter")); var _icon = require("../icon"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var isStringNumRegex = /\d+,?/; /** * 提供一个快速的表格数据渲染容器,不需要关注具体如何渲染,只需要传入对应的数据和过滤器 * * @export * @class TableBody * @extends {MapperFilter} */ var TableBody = /*#__PURE__*/ function (_MapperFilter) { _inherits(TableBody, _MapperFilter); function TableBody(props) { var _this; _classCallCheck(this, TableBody); _this = _possibleConstructorReturn(this, _getPrototypeOf(TableBody).call(this, props)); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "excludeField", /action|checkbox/); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "clearCheckeds", function () { _this.toggleAllItems(false); }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "toggleSelectItem", function (item, idx) { var nextCheckedItems = _this.state.checkedItems; if (nextCheckedItems[idx]) { delete nextCheckedItems[idx]; } else { nextCheckedItems[idx] = item; } _this.selectItems(nextCheckedItems, idx); }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getCheckbox", function (str, item, mapper, idx) { var checkedItems = _this.state.checkedItems; var checked = !!checkedItems[idx]; return _react.default.createElement("input", { type: "checkbox", checked: checked, onChange: function onChange(e) { return _this.toggleSelectItem(item, idx); } }); }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getKeyMapper", function () { var _this$props = _this.props, _this$props$keyMapper = _this$props.keyMapper, keyMapper = _this$props$keyMapper === void 0 ? [] : _this$props$keyMapper, needCheck = _this$props.needCheck; var result = keyMapper; if (needCheck) { var checkExtend = { key: 'checkbox', w: 30, filter: _this.getCheckbox }; result = [checkExtend].concat(_toConsumableArray(keyMapper)); } return result; }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "resizeCalcSize", function () { var containerWidth = _this.state.containerWidth; if (containerWidth != 'auto' && containerWidth < _this.tableRenderDOM.offsetWidth) { _this.setState({ containerWidth: 'auto' }); } _this.calcSize(); }); _this.state = { headerWidthMapper: [], containerWidth: 'auto', sortField: '', isDesc: false, checkedItems: {} }; _this.firstTDDOMs = {}; _this.sameSortTime = 0; return _this; } _createClass(TableBody, [{ key: "componentDidMount", value: function componentDidMount() { window.addEventListener('resize', this.resizeCalcSize); this.calcSize(); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { window.removeEventListener('resize', this.resizeCalcSize); } }, { key: "componentDidUpdate", value: function componentDidUpdate() { this.calcSize(); } /** * 清除所有已选择的内容 * * @memberof TableBody * @public */ }, { key: "toggleAllItems", value: function toggleAllItems(allCheck) { var nextCheckedItems = this.state.checkedItems; if (!allCheck) { nextCheckedItems = {}; } else { this.props.records.forEach(function (item, idx) { return nextCheckedItems[idx] = item; }); } this.selectItems(nextCheckedItems); } }, { key: "selectItems", value: function selectItems(nextState, idx) { var onCheck = this.props.onCheck; this.checkedItems = nextState; this.setState({ checkedItems: nextState }); (0, _basicHelper.Call)(onCheck, nextState, idx); } }, { key: "calcSize", value: function calcSize() { var _this2 = this; var nextHeaderWidthMapper = {}; var nextContainerWidth = 0; Object.keys(this.firstTDDOMs).forEach(function (tdIdx) { var currTDDOM = _this2.firstTDDOMs[tdIdx]; nextHeaderWidthMapper[tdIdx] = currTDDOM.offsetWidth; nextContainerWidth += nextHeaderWidthMapper[tdIdx]; }); if (JSON.stringify(nextHeaderWidthMapper) !== JSON.stringify(this.state.headerWidthMapper)) { var tableRenderWidth = this.tableRenderDOM.offsetWidth; this.setState({ headerWidthMapper: nextHeaderWidthMapper, containerWidth: nextContainerWidth > tableRenderWidth ? nextContainerWidth : 'auto' }); } } }, { key: "ignoreFilter", value: function ignoreFilter(str) { return this.props.sortIgnores.indexOf(str) !== -1; } }, { key: "getMapperItemsDOM", value: function getMapperItemsDOM(record, parentIdx, needCount) { var _this3 = this; var needAction = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; if (!record) return; var keyMapper = this.getKeyMapper(); var keyMapperLen = keyMapper.length; var result = []; var _loop = function _loop(_idx) { var item = keyMapper[_idx]; if (!item) return "continue"; var key = item.key; var currText = record[key]; var actionRes = !needAction && _this3.excludeField.test(key) ? '-' : _this3.mapperFilter(item, record, parentIdx); if (needCount) { var isNum = !isNaN(+currText) || isStringNumRegex.test(currText); if (isNum) { // 这里是处理累加的逻辑,如果为字符串的字段,则先把逗号去除 var isNumbTxt = +(currText + '').replace(',', ''); if (!isNaN(isNumbTxt) && typeof isNumbTxt === 'number') { _this3.statistics[key] = (_this3.statistics[key] || 0) + isNumbTxt; } } } result.push(_react.default.createElement("td", { ref: function ref(tdDOM) { if (tdDOM && parentIdx == 0) { _this3.firstTDDOMs[_idx] = tdDOM; } }, style: item.w ? { width: item.w, whiteSpace: 'pre-wrap' } : null, className: item.className || '', key: parentIdx + '_' + _idx }, actionRes)); }; for (var _idx = 0; _idx < keyMapperLen; _idx++) { var _ret = _loop(_idx); if (_ret === "continue") continue; } return result; } }, { key: "getStatisticDOM", value: function getStatisticDOM(record) { if (this.props.needCount && Object.keys(record).length > 0) return this.getMapperItemsDOM(record, 'statistics', false, false); } }, { key: "getHeaderWidth", value: function getHeaderWidth() { var headerWidthMapper = this.state.headerWidthMapper; var result = 0; var keyMapper = this.getKeyMapper(); keyMapper.forEach(function (item, idx) { if (item) result += headerWidthMapper[idx]; }); return result; } }, { key: "recordDescFilter", value: function recordDescFilter() { var _this$state = this.state, sortField = _this$state.sortField, isDesc = _this$state.isDesc; var records = this.props.records; if (!sortField) return records; var result = _toConsumableArray(records); result.sort(function (itemPrev, itemNext) { var sortTargetPrev = itemPrev[sortField]; var sortTargetNext = itemNext[sortField]; var res; switch (true) { case typeof sortTargetPrev == 'string': res = sortTargetPrev.localeCompare(sortTargetNext); break; case typeof sortTargetPrev == 'number': res = sortTargetPrev - sortTargetNext; break; } return isDesc ? res : res * -1; }); return result; } }, { key: "orderRecord", value: function orderRecord(orderKey) { var _this4 = this; if (this.ignoreFilter(orderKey)) return; this.setState(function (_ref) { var isDesc = _ref.isDesc, sortField = _ref.sortField; var _isDesc = isDesc; if (sortField == orderKey) { _this4.sameSortTime += 1; if (_this4.sameSortTime === 2) { _isDesc = false; orderKey = ''; _this4.sameSortTime = 0; } else { _isDesc = !_isDesc; } } else { _this4.sameSortTime = 0; _isDesc = false; } return { sortField: orderKey, isDesc: _isDesc }; }); } }, { key: "render", value: function render() { var _this5 = this; var _this$props2 = this.props, needCount = _this$props2.needCount, height = _this$props2.height, whenCheckAction = _this$props2.whenCheckAction; var _this$state2 = this.state, headerWidthMapper = _this$state2.headerWidthMapper, containerWidth = _this$state2.containerWidth, sortField = _this$state2.sortField, isDesc = _this$state2.isDesc, checkedItems = _this$state2.checkedItems; var records = this.recordDescFilter(); var hasRecord = records.length > 0; var keyMapper = this.getKeyMapper(); var isAllCheck = Object.keys(checkedItems).length == records.length; if (!Array.isArray(records)) { console.error('records 必须为 []'); return _react.default.createElement("span", null); } /** 统计字段,每一次统计都是一个新对象 */ this.statistics = {}; var hasChecked = Object.keys(checkedItems).length != 0; var tableHeader = _react.default.createElement("div", { className: "table-body-scroll", style: { width: containerWidth } }, _react.default.createElement("table", { className: "table nomargin table-header" }, _react.default.createElement("thead", null, _react.default.createElement("tr", null, keyMapper.map(function (item, idx) { if (!item) return; var currHeaderWidth = item.w || headerWidthMapper[idx]; var title = item.title || window.$UKE.getKeyMap(item.key); switch (true) { case item.key === 'checkbox': title = _react.default.createElement("input", { type: "checkbox", checked: isAllCheck, onChange: function onChange(e) { return _this5.toggleAllItems(e.target.checked); } }); break; case (0, _basicHelper.IsFunc)(title): title = title(item, idx); break; } var isOrdering = sortField == item.key; var sortTip = isOrdering ? _react.default.createElement("span", { className: "caret", style: { transform: "rotate(".concat(!isDesc ? '180deg' : '0deg', ")") } }) : null; return _react.default.createElement("th", { className: "".concat(isOrdering ? '_order ' + (isDesc ? '_desc ' : '_asc ') : '', "_btn"), key: item.key, onClick: function onClick(e) { return _this5.orderRecord(item.key); }, style: { width: currHeaderWidth } }, title, sortTip); }))))); var tableBody = hasRecord ? _react.default.createElement("div", { className: "table-body-scroll", style: { height: height, width: containerWidth } }, _react.default.createElement("table", { className: "table nomargin table-body" }, _react.default.createElement("tbody", null, records.map(function (record, _idx) { if (!record) return; var _record$_highlight = record._highlight, _highlight = _record$_highlight === void 0 ? '' : _record$_highlight; var idx = _idx; return _react.default.createElement("tr", { key: idx, className: _highlight }, _this5.getMapperItemsDOM(record, idx, needCount)); }), this.props.needCount ? _react.default.createElement("tr", { className: "theme" }, this.getStatisticDOM(this.statistics)) : null))) : _react.default.createElement("span", { className: "no-record-tip" }, _react.default.createElement(_icon.Icon, { n: "noData" }), _react.default.createElement("span", { className: "text" }, "\u6682\u65E0\u8BB0\u5F55")); return _react.default.createElement("div", { className: "table-render" + (hasChecked ? ' has-checked' : ''), ref: function ref(tableRenderDOM) { if (tableRenderDOM) _this5.tableRenderDOM = tableRenderDOM; } }, hasChecked && !!whenCheckAction ? _react.default.createElement("div", { className: "checked-actions" }, whenCheckAction) : null, tableHeader, tableBody); } }]); return TableBody; }(_mapperFilter.default); exports.default = TableBody; _defineProperty(TableBody, "propTypes", { /** 定义数据渲染的字段的映射配置 */ keyMapper: _propTypes.default.arrayOf(_propTypes.default.shape({ /** 字段的 key */ key: _propTypes.default.string.isRequired, /** 该字段的过滤器函数,可以返回任意类型 */ filter: _propTypes.default.func, /** 是否日期+时分秒 */ datetime: _propTypes.default.any, /** 是否日期 */ date: _propTypes.default.any, /** 是否格式化成金钱 */ money: _propTypes.default.any, /** 单个格子的宽度 */ w: _propTypes.default.any, /** 是否以绝对值格式化成金钱 */ abvMoney: _propTypes.default.any, /** 该字段的值的映射 mapper */ namesMapper: _propTypes.default.shape({ key: _propTypes.default.string }) })).isRequired, /** 需要渲染的目标记录 */ records: _propTypes.default.arrayOf(_propTypes.default.object).isRequired, /** 是否需要统计 */ needCount: _propTypes.default.bool, /** 是否多选 */ needCheck: _propTypes.default.bool, /** 无视的排序字段 */ sortIgnores: _propTypes.default.arrayOf(_propTypes.default.string), /** 当选中时往表格顶部嵌入的内容 */ whenCheckAction: _propTypes.default.any }); _defineProperty(TableBody, "defaultProps", { sortIgnores: ['checkbox'], needCheck: false, needCount: false });