@bpanel/bpanel-ui
Version:
reusable React component library used in the bpanel GUI
338 lines (278 loc) • 11.1 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
var _entries = require('babel-runtime/core-js/object/entries');
var _entries2 = _interopRequireDefault(_entries);
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _reactVirtualized = require('react-virtualized');
var _HeaderRow = require('./HeaderRow');
var _HeaderRow2 = _interopRequireDefault(_HeaderRow);
var _rowRenderer2 = require('./rowRenderer');
var _rowRenderer3 = _interopRequireDefault(_rowRenderer2);
var _Text = require('../Text');
var _Text2 = _interopRequireDefault(_Text);
var _utils = require('../../utils');
require('react-virtualized/styles.css');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var Table = function (_PureComponent) {
(0, _inherits3.default)(Table, _PureComponent);
function Table() {
(0, _classCallCheck3.default)(this, Table);
var _this = (0, _possibleConstructorReturn3.default)(this, (Table.__proto__ || (0, _getPrototypeOf2.default)(Table)).call(this));
_this.state = {
/**
* selectedIndex tracks the row in the table that is selected
* Its value is the index of the row in the table
* hoverIndex is similar, for mouseOver state
*/
selectedIndex: undefined,
hoverIndex: null
};
_this.selectRow = _this.selectRow.bind(_this);
return _this;
}
(0, _createClass3.default)(Table, [{
key: 'getColProps',
/**
* getColProps sets the header(top row) data for the table.
*/
value: function getColProps() {
var _props = this.props,
colProps = _props.colProps,
tableData = _props.tableData,
colHeaders = _props.colHeaders;
if (colProps) return colProps;
var headers = Array.isArray(colHeaders) ? colHeaders : (0, _entries2.default)(tableData[0]).map(function (header) {
return Array.isArray(header) ? header[0] : header;
});
return headers.map(function (header) {
return {
label: header,
dataKey: header,
width: 400,
flexGrow: 1,
cellRenderer: function cellRenderer(_ref) {
var _ref$cellData = _ref.cellData,
cellData = _ref$cellData === undefined ? '' : _ref$cellData;
// wrap strings in text components
if (typeof cellData === 'string') return _react2.default.createElement(
_Text2.default,
null,
cellData
);
// allow for custom react components to be returned
return cellData;
},
headerRenderer: function headerRenderer(_ref2) {
var label = _ref2.label;
return _react2.default.createElement(
_Text2.default,
null,
label && label.toString()
);
}
};
});
}
/**
* getTableHeight gets height of the table. Calculates the height of the table
* if a row is expanded.
*/
}, {
key: 'getTableHeight',
value: function getTableHeight(tableData, selectedIndex, openHeight) {
openHeight = openHeight ? openHeight : 0; // selectable but not expandable
return (tableData.length + 1) * 30 + (selectedIndex || selectedIndex === 0 ? openHeight : 0);
}
/**
* selectRow updates selectedIndex when a row is clicked.
*/
}, {
key: 'selectRow',
value: function selectRow(_ref3) {
var index = _ref3.index;
var expandedHeight = this.props.expandedHeight;
var _state = this.state,
selectedIndex = _state.selectedIndex,
hoverIndex = _state.hoverIndex;
var unselect = expandedHeight ? undefined : index;
var updateIndex = index === selectedIndex ? unselect : index;
this.setState({ selectedIndex: updateIndex });
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var _props2 = this.props,
tableData = _props2.tableData,
ExpandedComponent = _props2.ExpandedComponent,
expandedHeight = _props2.expandedHeight,
expandedData = _props2.expandedData,
onRowClick = _props2.onRowClick,
headerHeight = _props2.headerHeight,
rowHeight = _props2.rowHeight,
rowStyle = _props2.rowStyle,
_props2$style = _props2.style,
containerStyle = _props2$style.containerStyle,
innerContainerStyle = _props2$style.innerContainerStyle,
headerStyle = _props2$style.headerStyle,
bodyStyle = _props2$style.bodyStyle,
theme = _props2.theme,
selectable = _props2.selectable,
tableProps = (0, _objectWithoutProperties3.default)(_props2, ['tableData', 'ExpandedComponent', 'expandedHeight', 'expandedData', 'onRowClick', 'headerHeight', 'rowHeight', 'rowStyle', 'style', 'theme', 'selectable']);
var _theme$table = theme.table,
containerCss = _theme$table.container,
headerCss = _theme$table.header,
bodyCss = _theme$table.body,
hoverExpandableRow = _theme$table.hoverExpandableRow,
hoverRow = _theme$table.hoverRow,
selectedRow = _theme$table.selectedRow,
tableRowStyle = theme.tableRowStyle,
expandedRowStyles = theme.expandedRow;
var _state2 = this.state,
selectedIndex = _state2.selectedIndex,
hoverIndex = _state2.hoverIndex;
var _colProps = this.getColProps();
var tableHeight = this.getTableHeight(tableData, selectedIndex, expandedHeight);
var rowRendererOptions = {
selectedIndex: selectedIndex,
ExpandedComponent: ExpandedComponent,
expandedHeight: expandedHeight,
expandedData: expandedData,
rowHeight: rowHeight,
hoverExpandableRow: hoverExpandableRow,
hoverRow: hoverRow,
selectedRow: selectedRow,
hoverIndex: hoverIndex,
expandedRowStyles: expandedRowStyles,
tableData: tableData,
theme: theme,
selectable: selectable
};
// custom click actions for certain table formats
var rowOnClick = function rowOnClick(e) {
if (expandedHeight || selectable) {
_this2.selectRow(e);
}
// custom function has been passed as a property
if (onRowClick) {
onRowClick(e);
}
// default: do nothing
return;
};
// mouse hover actions
var rowOnMouseOver = function rowOnMouseOver(e) {
_this2.setState({ hoverIndex: e.index });
};
var rowOnMouseOut = function rowOnMouseOut(e) {
_this2.setState({ hoverIndex: null });
};
return _react2.default.createElement(
'div',
{ className: containerCss, style: containerStyle },
_react2.default.createElement(
_reactVirtualized.AutoSizer,
{ disableHeight: true },
function (_ref4) {
var width = _ref4.width;
return _react2.default.createElement(
_reactVirtualized.Table,
(0, _extends3.default)({
className: bodyCss,
height: tableHeight,
containerStyle: innerContainerStyle || { overflow: 'visible' },
headerClassName: headerCss,
headerHeight: headerHeight,
headerRowRenderer: function headerRowRenderer(props) {
return _react2.default.createElement(_HeaderRow2.default, props);
},
headerStyle: headerStyle,
onRowClick: rowOnClick,
onRowMouseOver: rowOnMouseOver,
onRowMouseOut: rowOnMouseOut,
rowCount: tableData.length,
rowGetter: function rowGetter(_ref5) {
var index = _ref5.index;
return tableData[index];
},
rowHeight: rowHeight,
rowRenderer: function rowRenderer(options) {
return (0, _rowRenderer3.default)(options, rowRendererOptions);
},
rowStyle: rowStyle || tableRowStyle,
width: width
}, tableProps),
_colProps.map(function (colProp) {
return _react2.default.createElement(_reactVirtualized.Column, (0, _extends3.default)({ key: 'table-' + colProp.dataKey }, colProp));
})
);
}
)
);
}
}], [{
key: 'getDerivedStateFromProps',
/*
* getDerivedStateFromProps is invoked right before calling the render method
* we use it here to force-change the selected index of this table,
* from a prop setSelectedIndex that can be set by some other object
* a value of -1 means no change
*/
value: function getDerivedStateFromProps(props, state) {
if (props.setSelectedIndex >= 0) {
return (0, _extends3.default)({}, state, {
selectedIndex: props.setSelectedIndex
});
}
return null;
}
}, {
key: 'propTypes',
get: function get() {
return {
ExpandedComponent: _propTypes2.default.oneOfType([_propTypes2.default.node, _propTypes2.default.func]),
colProps: _propTypes2.default.arrayOf(_propTypes2.default.shape({
label: _propTypes2.default.string,
dataKey: _propTypes2.default.string,
width: _propTypes2.default.number
})),
colHeaders: _propTypes2.default.arrayOf(_propTypes2.default.string)
};
}
}, {
key: 'defaultProps',
get: function get() {
return {
ExpandedComponent: function ExpandedComponent() {},
headerHeight: 30,
rowHeight: 30,
style: {
bodyStyle: {},
containerStyle: {},
headerStyle: {}
}
};
}
}]);
return Table;
}(_react.PureComponent);
exports.default = (0, _utils.connectTheme)(Table);