react-super-treeview
Version:
React Super Treeview
601 lines (493 loc) • 21.2 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["ExpandableTree"] = factory();
else
root["ExpandableTree"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "dist/";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"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; };
var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
__webpack_require__(1);
var _react = __webpack_require__(2);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(3);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _isNil = __webpack_require__(4);
var _isNil2 = _interopRequireDefault(_isNil);
var _isEmpty = __webpack_require__(5);
var _isEmpty2 = _interopRequireDefault(_isEmpty);
var _isEqual = __webpack_require__(6);
var _isEqual2 = _interopRequireDefault(_isEqual);
var _find = __webpack_require__(7);
var _find2 = _interopRequireDefault(_find);
var _get = __webpack_require__(8);
var _get2 = _interopRequireDefault(_get);
var _cloneDeep = __webpack_require__(9);
var _cloneDeep2 = _interopRequireDefault(_cloneDeep);
var _reactTransitionGroup = __webpack_require__(10);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: 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) : subClass.__proto__ = superClass; }
var SuperTreeview = function (_Component) {
_inherits(SuperTreeview, _Component);
function SuperTreeview(props) {
_classCallCheck(this, SuperTreeview);
var _this = _possibleConstructorReturn(this, (SuperTreeview.__proto__ || Object.getPrototypeOf(SuperTreeview)).call(this, props));
_this.state = {
data: (0, _cloneDeep2.default)(_this.props.data),
lastCheckToggledNodeIndex: null
};
_this.handleUpdate = _this.handleUpdate.bind(_this);
_this.printNodes = _this.printNodes.bind(_this);
_this.printChildren = _this.printChildren.bind(_this);
_this.printCheckbox = _this.printCheckbox.bind(_this);
_this.printDeleteButton = _this.printDeleteButton.bind(_this);
_this.printExpandButton = _this.printExpandButton.bind(_this);
_this.printNoChildrenMessage = _this.printNoChildrenMessage.bind(_this);
_this.handleCheckToggle = _this.handleCheckToggle.bind(_this);
_this.handleDelete = _this.handleDelete.bind(_this);
_this.handleExpandToggle = _this.handleExpandToggle.bind(_this);
return _this;
}
_createClass(SuperTreeview, [{
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
if (!(0, _isEqual2.default)(nextProps.data, this.props.data)) {
this.setState({ data: (0, _cloneDeep2.default)(nextProps.data) });
}
}
}, {
key: 'handleUpdate',
value: function handleUpdate(updatedData) {
var _props = this.props,
depth = _props.depth,
onUpdateCb = _props.onUpdateCb;
onUpdateCb(updatedData, depth);
}
}, {
key: 'handleCheckToggle',
value: function handleCheckToggle(node, e) {
var _props2 = this.props,
onCheckToggleCb = _props2.onCheckToggleCb,
depth = _props2.depth;
var lastCheckToggledNodeIndex = this.state.lastCheckToggledNodeIndex;
var data = (0, _cloneDeep2.default)(this.state.data);
var currentNode = (0, _find2.default)(data, node);
var currentNodeIndex = data.indexOf(currentNode);
var toggledNodes = [];
if (e.shiftKey && !(0, _isNil2.default)(lastCheckToggledNodeIndex)) {
var rangeStart = Math.min(currentNodeIndex, lastCheckToggledNodeIndex);
var rangeEnd = Math.max(currentNodeIndex, lastCheckToggledNodeIndex);
var nodeRange = data.slice(rangeStart, rangeEnd + 1);
nodeRange.forEach(function (node) {
node.isChecked = e.target.checked;
toggledNodes.push(node);
});
} else {
currentNode.isChecked = e.target.checked;
toggledNodes.push(currentNode);
}
onCheckToggleCb(toggledNodes, depth);
this.setState({ lastCheckToggledNodeIndex: currentNodeIndex });
this.handleUpdate(data);
}
}, {
key: 'handleDelete',
value: function handleDelete(node) {
var _props3 = this.props,
onDeleteCb = _props3.onDeleteCb,
depth = _props3.depth;
var data = (0, _cloneDeep2.default)(this.state.data);
var newData = data.filter(function (nodeItem) {
return !(0, _isEqual2.default)(node, nodeItem);
});
onDeleteCb(node, newData, depth) && this.handleUpdate(newData);
}
}, {
key: 'handleExpandToggle',
value: function handleExpandToggle(node) {
var _props4 = this.props,
onExpandToggleCb = _props4.onExpandToggleCb,
depth = _props4.depth;
var data = (0, _cloneDeep2.default)(this.state.data);
var currentNode = (0, _find2.default)(data, node);
currentNode.isExpanded = !currentNode.isExpanded;
onExpandToggleCb(currentNode, depth);
this.handleUpdate(data);
}
}, {
key: 'printCheckbox',
value: function printCheckbox(node) {
var _this2 = this;
var _props5 = this.props,
isCheckable = _props5.isCheckable,
keywordLabel = _props5.keywordLabel,
depth = _props5.depth;
if (isCheckable(node, depth)) {
return _react2.default.createElement('input', {
type: 'checkbox',
name: node[keywordLabel],
onClick: function onClick(e) {
_this2.handleCheckToggle(node, e);
},
checked: !!node.isChecked,
id: node.id
});
}
}
}, {
key: 'printDeleteButton',
value: function printDeleteButton(node) {
var _this3 = this;
var _props6 = this.props,
isDeletable = _props6.isDeletable,
depth = _props6.depth,
deleteElement = _props6.deleteElement;
if (isDeletable(node, depth)) {
return _react2.default.createElement(
'div',
{ className: 'delete-btn',
onClick: function onClick() {
_this3.handleDelete(node);
}
},
deleteElement
);
}
}
}, {
key: 'printExpandButton',
value: function printExpandButton(node) {
var _this4 = this;
var className = node.isExpanded ? 'super-treeview-triangle-btn-down' : 'super-treeview-triangle-btn-right';
var _props7 = this.props,
isExpandable = _props7.isExpandable,
depth = _props7.depth;
if (isExpandable(node, depth)) {
return _react2.default.createElement('div', {
className: 'super-treeview-triangle-btn ' + className,
onClick: function onClick() {
_this4.handleExpandToggle(node);
}
});
} else {
return _react2.default.createElement('div', { className: 'super-treeview-triangle-btn super-treeview-triangle-btn-none' });
}
}
}, {
key: 'printNoChildrenMessage',
value: function printNoChildrenMessage() {
var _props8 = this.props,
transitionExitTimeout = _props8.transitionExitTimeout,
noChildrenAvailableMessage = _props8.noChildrenAvailableMessage;
var noChildrenTransitionProps = {
classNames: 'super-treeview-no-children-transition',
key: 'super-treeview-no-children',
style: {
transitionDuration: transitionExitTimeout + 'ms',
transitionDelay: transitionExitTimeout + 'ms'
},
timeout: {
enter: transitionExitTimeout
},
exit: false
};
return _react2.default.createElement(
_reactTransitionGroup.CSSTransition,
noChildrenTransitionProps,
_react2.default.createElement(
'div',
{ className: 'super-treeview-no-children' },
_react2.default.createElement(
'div',
{ className: 'super-treeview-no-children-content' },
noChildrenAvailableMessage
)
)
);
}
}, {
key: 'printNodes',
value: function printNodes(nodeArray) {
var _props9 = this.props,
keywordKey = _props9.keywordKey,
keywordLabel = _props9.keywordLabel,
depth = _props9.depth,
transitionEnterTimeout = _props9.transitionEnterTimeout,
transitionExitTimeout = _props9.transitionExitTimeout,
getStyleClassCb = _props9.getStyleClassCb;
var printExpandButton = this.printExpandButton,
printCheckbox = this.printCheckbox,
printDeleteButton = this.printDeleteButton,
printChildren = this.printChildren;
var nodeTransitionProps = {
classNames: 'super-treeview-node-transition',
style: {
transitionDuration: transitionEnterTimeout + 'ms'
},
timeout: {
enter: transitionEnterTimeout,
exit: transitionExitTimeout
}
};
return _react2.default.createElement(
_reactTransitionGroup.TransitionGroup,
null,
(0, _isEmpty2.default)(nodeArray) ? this.printNoChildrenMessage() : nodeArray.map(function (node, index) {
var nodeText = (0, _get2.default)(node, keywordLabel, '');
return _react2.default.createElement(
_reactTransitionGroup.CSSTransition,
_extends({}, nodeTransitionProps, {
key: node[keywordKey] || index
}),
_react2.default.createElement(
'div',
{
className: 'super-treeview-node' + getStyleClassCb(node)
},
_react2.default.createElement(
'div',
{ className: 'super-treeview-node-content' },
printExpandButton(node, depth),
printCheckbox(node, depth),
_react2.default.createElement(
'label',
{
htmlFor: node.id,
title: nodeText,
className: 'super-treeview-text'
},
nodeText
),
printDeleteButton(node, depth)
),
printChildren(node)
)
);
})
);
}
}, {
key: 'printChildren',
value: function printChildren(node) {
if (!node.isExpanded) {
return null;
}
var _props10 = this.props,
keywordChildren = _props10.keywordChildren,
keywordChildrenLoading = _props10.keywordChildrenLoading,
depth = _props10.depth;
var isChildrenLoading = (0, _get2.default)(node, keywordChildrenLoading, false);
var childrenElement = void 0;
if (isChildrenLoading) {
childrenElement = (0, _get2.default)(this.props, 'loadingElement');
} else {
childrenElement = _react2.default.createElement(SuperTreeview, _extends({}, this.props, {
data: node[keywordChildren] || [],
depth: depth + 1,
onUpdateCb: onChildrenUpdateCb.bind(this)
}));
}
return _react2.default.createElement(
'div',
{ className: 'super-treeview-children-container' },
childrenElement
);
function onChildrenUpdateCb(updatedData) {
var data = (0, _cloneDeep2.default)(this.state.data);
var currentNode = (0, _find2.default)(data, node);
currentNode[keywordChildren] = updatedData;
this.handleUpdate(data);
}
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
{ className: 'super-treeview' },
this.printNodes(this.state.data)
);
}
}]);
return SuperTreeview;
}(_react.Component);
SuperTreeview.propTypes = {
data: _propTypes2.default.array.isRequired,
depth: _propTypes2.default.number,
deleteElement: _propTypes2.default.element,
getStyleClassCb: _propTypes2.default.func,
isCheckable: _propTypes2.default.func,
isDeletable: _propTypes2.default.func,
isExpandable: _propTypes2.default.func,
keywordChildren: _propTypes2.default.string,
keywordChildrenLoading: _propTypes2.default.string,
keywordKey: _propTypes2.default.string,
keywordLabel: _propTypes2.default.string,
loadingElement: _propTypes2.default.element,
noChildrenAvailableMessage: _propTypes2.default.string,
onCheckToggleCb: _propTypes2.default.func,
onDeleteCb: _propTypes2.default.func,
onExpandToggleCb: _propTypes2.default.func,
onUpdateCb: _propTypes2.default.func,
transitionEnterTimeout: _propTypes2.default.number,
transitionExitTimeout: _propTypes2.default.number
};
SuperTreeview.defaultProps = {
depth: 0,
deleteElement: _react2.default.createElement(
'div',
null,
'(X)'
),
getStyleClassCb: function getStyleClassCb() /* node, depth */{
return '';
},
isCheckable: function isCheckable() /* node, depth */{
return true;
},
isDeletable: function isDeletable() /* node, depth */{
return true;
},
isExpandable: function isExpandable() /* node, depth */{
return true;
},
keywordChildren: 'children',
keywordChildrenLoading: 'isChildrenLoading',
keywordLabel: 'name',
keywordKey: 'id',
loadingElement: _react2.default.createElement(
'div',
null,
'loading...'
),
noChildrenAvailableMessage: 'No data found',
onCheckToggleCb: function onCheckToggleCb() /* Array of nodes, depth */{},
onDeleteCb: function onDeleteCb() /* node, updatedData, depth */{
return true;
},
onExpandToggleCb: function onExpandToggleCb() /* node, depth */{},
onUpdateCb: function onUpdateCb() /* updatedData, depth */{},
transitionEnterTimeout: 1200,
transitionExitTimeout: 1200
};
exports.default = SuperTreeview;
/***/ }),
/* 1 */
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ }),
/* 2 */
/***/ (function(module, exports) {
module.exports = require("react");
/***/ }),
/* 3 */
/***/ (function(module, exports) {
module.exports = require("prop-types");
/***/ }),
/* 4 */
/***/ (function(module, exports) {
module.exports = require("lodash/isNil");
/***/ }),
/* 5 */
/***/ (function(module, exports) {
module.exports = require("lodash/isEmpty");
/***/ }),
/* 6 */
/***/ (function(module, exports) {
module.exports = require("lodash/isEqual");
/***/ }),
/* 7 */
/***/ (function(module, exports) {
module.exports = require("lodash/find");
/***/ }),
/* 8 */
/***/ (function(module, exports) {
module.exports = require("lodash/get");
/***/ }),
/* 9 */
/***/ (function(module, exports) {
module.exports = require("lodash/cloneDeep");
/***/ }),
/* 10 */
/***/ (function(module, exports) {
module.exports = require("react-transition-group");
/***/ })
/******/ ]);
});