UNPKG

react-conventions

Version:

An open source set of React components that implement Ambassador's Design and UX patterns.

250 lines (199 loc) 9.08 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); 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; }; }(); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _Icon = require('../Icon'); var _Icon2 = _interopRequireDefault(_Icon); var _style = require('./style.scss'); var _style2 = _interopRequireDefault(_style); var _immutable = require('immutable'); var _immutable2 = _interopRequireDefault(_immutable); 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 Breadcrumb = function (_React$Component) { _inherits(Breadcrumb, _React$Component); function Breadcrumb(props) { _classCallCheck(this, Breadcrumb); var _this = _possibleConstructorReturn(this, (Breadcrumb.__proto__ || Object.getPrototypeOf(Breadcrumb)).call(this, props)); _this.state = { minimized: false, childrenWidth: 0, dropdownOpen: false, routes: _immutable2.default.fromJS(_this.props.routes) }; _this.handleResize = function () { var breadcrumbsStyle = window.getComputedStyle(_this._breadcrumbsContainer); var breadcrumbsRect = _this._breadcrumbsContainer.getBoundingClientRect(); var offsetValue = _this.props.offset || 0; var calculatedBreadcrumbWidth = breadcrumbsRect.width - (parseInt(breadcrumbsStyle.paddingLeft) + parseInt(breadcrumbsStyle.paddingRight)) - offsetValue; if (_this.state.routes.size > 1 && _this.state.childrenWidth > calculatedBreadcrumbWidth) { _this.setState({ minimized: true }); } else { _this.setState({ minimized: false, dropdownOpen: false }); } }; _this.getChildrenWidth = function () { var children = [].slice.call(_this._breadcrumbsContainer.children); var width = 0; children.map(function (element, index) { var elemStyles = window.getComputedStyle(element); width += element.getBoundingClientRect().width + parseInt(elemStyles.marginLeft) + parseInt(elemStyles.marginRight); }); return width; }; _this.getDropdownChildrenHeight = function () { var children = [].slice.call(_this._breadcrumbsDropdown.children); var height = 0; children.map(function (element, index) { var elemStyles = window.getComputedStyle(element); height += element.getBoundingClientRect().height; }); return height; }; _this.componentWillReceiveProps = function (nextProps) { _this.setState({ childrenWidth: _this.getChildrenWidth(), routes: _immutable2.default.fromJS(nextProps.routes) }, function () { _this.handleResize(); }); }; _this.componentDidMount = function () { _this.setState({ childrenWidth: _this.getChildrenWidth() }, function () { _this.handleResize(); window.addEventListener('resize', _this.handleResize); }); }; _this.componentWillUnmount = function () { window.removeEventListener('resize', _this.handleResize); document.removeEventListener('click', _this.toggleDropdown); }; _this.toggleDropdown = function () { _this.setState({ dropdownOpen: !_this.state.dropdownOpen }, function () { if (_this.state.dropdownOpen) { document.addEventListener('click', _this.toggleDropdown); } else { document.removeEventListener('click', _this.toggleDropdown); } }); }; _this.shouldComponentUpdate = function (nextProps, nextState) { return nextState.minimized !== _this.state.minimized || nextState.dropdownOpen !== _this.state.dropdownOpen || !_immutable2.default.is(nextState.routes, _this.state.routes); }; _this.getTags = function () { var depth = _this.state.routes.size; var that = _this; var rootRendered = false; return _this.state.routes.map(function (item, index) { var title = item.get('title'); if (title === undefined) return; var tags = []; if (!that.state.minimized && rootRendered) { tags.push(_react2.default.createElement(_Icon2.default, { key: index, name: 'icon-arrow-68', className: _style2.default['icon-arrow-68'], width: '14', height: '14', color: '#879098' })); tags.push(_react2.default.createElement( 'span', { className: _style2.default.secondary }, title )); return tags; } if (!that.state.minimized) { tags.push(_react2.default.createElement( 'h2', { className: _style2.default.primary }, title )); rootRendered = true; return tags; } if (rootRendered && index === depth - 1) { tags.push(_react2.default.createElement(_Icon2.default, { key: index, name: 'icon-arrow-68', className: _style2.default['icon-arrow-68'], width: '14', height: '14', color: '#879098' })); tags.push(_react2.default.createElement( 'span', { className: _style2.default.secondary }, title )); return tags; } if (!rootRendered) { tags.push(_react2.default.createElement( 'span', { className: _style2.default.ellipsis, onClick: that.toggleDropdown }, '...' )); rootRendered = true; return tags; } }); }; _this.getHiddenTags = function () { var depth = _this.state.routes.size; return _this.state.routes.map(function (item, index) { var title = item.get('title'); if (title === undefined) return; var tags = []; if (index + 1 < depth) { tags.push(_react2.default.createElement( 'li', { className: _style2.default['dropdown-item'] }, title )); } return tags; }); }; _this.getStyle = function () { var style = { height: '0px', opacity: '0', transition: 'height 250ms cubic-bezier(0.46, 0.03, 0.52, 0.96) 0ms, opacity 0ms cubic-bezier(0.46, 0.03, 0.52, 0.96) 250ms' }; if (_this.state.dropdownOpen && _this.state.minimized) { style.height = _this.getDropdownChildrenHeight() + 'px'; style.opacity = '1'; style.transition = 'height 250ms cubic-bezier(0.46, 0.03, 0.52, 0.96) 0ms, opacity 250ms cubic-bezier(0.46, 0.03, 0.52, 0.96) 0ms'; } return style; }; return _this; } _createClass(Breadcrumb, [{ key: 'render', value: function render() { var _this2 = this; var breadcrumbs = this.getTags(); return _react2.default.createElement( 'div', { className: _style2.default['breadcrumbs-container'] }, _react2.default.createElement( 'div', { className: _style2.default.breadcrumb, ref: function ref(c) { return _this2._breadcrumbsContainer = c; } }, this.getTags() ), _react2.default.createElement( 'ul', { className: _style2.default['breadcrumbs-dropdown'], style: this.getStyle(), ref: function ref(c) { return _this2._breadcrumbsDropdown = c; } }, this.getHiddenTags() ) ); } }]); return Breadcrumb; }(_react2.default.Component); Breadcrumb.propTypes = { /** * The array of routes to generate the Breadcrumbs. */ routes: _react2.default.PropTypes.array.isRequired, /** * Optional offset to trigger 'minimize' state. */ offset: _react2.default.PropTypes.number }; exports.default = Breadcrumb;