UNPKG

@carbon/ibm-security

Version:

Carbon for Cloud & Cognitive IBM Security UI components

196 lines (190 loc) 10.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _classnames = _interopRequireDefault(require("classnames")); var _propTypes = _interopRequireDefault(require("prop-types")); var _react = _interopRequireWildcard(require("react")); var _Button = _interopRequireDefault(require("../Button")); var _ScrollGradient = _interopRequireDefault(require("../ScrollGradient")); var _namespace = require("../../globals/namespace"); var _theme = _interopRequireDefault(require("../../globals/theme")); var _excluded = ["as", "children", "className", "expandButtonClassName", "getExpandButtonLabel", "scrollGradientColor", "truncateThreshold", "collapsedItemLimit", "expandedItemLimit"]; function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } /** * @file Truncated list component. * @copyright IBM Security 2020 - 2021 */ var namespace = (0, _namespace.getComponentNamespace)('truncated-list'); var toArray = _react.Children.toArray; var TruncatedList = /*#__PURE__*/function (_Component) { function TruncatedList() { var _this; (0, _classCallCheck2.default)(this, TruncatedList); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _callSuper(this, TruncatedList, [].concat(args)); (0, _defineProperty2.default)(_this, "state", { isExpanded: false }); (0, _defineProperty2.default)(_this, "handleExpand", function () { // Pre-set the height of the list container to its own current height so we can smoothly // transition into its new height in the React Effect hook. _this.updateListContainerHeight(); _this.setState(function (_ref) { var isExpanded = _ref.isExpanded; return { isExpanded: !isExpanded }; }); }); (0, _defineProperty2.default)(_this, "listContainer", null); (0, _defineProperty2.default)(_this, "setListContainer", function (listContainer) { return _this.listContainer = listContainer; }); return _this; } (0, _inherits2.default)(TruncatedList, _Component); return (0, _createClass2.default)(TruncatedList, [{ key: "getDisplayCount", value: /** * Defines how many items must be displayed at a time and whether it should truncate. */ function getDisplayCount(childrenLength) { var _this$props = this.props, collapsedItemLimit = _this$props.collapsedItemLimit, expandedItemLimit = _this$props.expandedItemLimit, truncateThreshold = _this$props.truncateThreshold, isExpanded = this.state.isExpanded; var shouldTruncate = childrenLength > truncateThreshold; // If we do not need to truncate, we can just show the entire list of items. if (!shouldTruncate) { return [childrenLength, shouldTruncate]; } // When the list is truncated and expanded, we use the expanded item limit. if (isExpanded) { return [expandedItemLimit, shouldTruncate]; } // If the truncate threshold is lower than the collapsed item limit, and the list needs to be // truncated, we must display the lowest of the two counts otherwise the expand button would // have a negative count. return [Math.min(collapsedItemLimit, truncateThreshold), shouldTruncate]; } /** * Adjusts the height of the list container so only the amount of items from the calculated * display amount can be viewed at a time. */ }, { key: "updateListContainerHeight", value: function updateListContainerHeight() { var listContainer = this.listContainer, children = this.props.children; if (!listContainer) { return; } var items = listContainer.firstElementChild.children; // Calculate which item in the list is the last to show in our list. It either has to be the // calculate display count or the last item on the list. Whichever comes first. var lastItemToShow = items[Math.min(this.getDisplayCount(toArray(children).length)[0], items.length - 1)]; listContainer.style.height = lastItemToShow.offsetTop + lastItemToShow.offsetHeight + 4 + 'px'; } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, _ref2) { var isExpanded = _ref2.isExpanded; // After the component's expanded state has changed update the height of the list container to be // the same as its visible children set. if (isExpanded != this.state.isExpanded) { this.updateListContainerHeight(); } } }, { key: "render", value: function render() { var _this$props2 = this.props, List = _this$props2.as, children = _this$props2.children, className = _this$props2.className, expandButtonClassName = _this$props2.expandButtonClassName, getExpandButtonLabel = _this$props2.getExpandButtonLabel, scrollGradientColor = _this$props2.scrollGradientColor, _ = _this$props2.truncateThreshold, __ = _this$props2.collapsedItemLimit, ___ = _this$props2.expandedItemLimit, other = (0, _objectWithoutProperties2.default)(_this$props2, _excluded), isExpanded = this.state.isExpanded; var childrenArray = toArray(children); var childrenLength = childrenArray.length; var _this$getDisplayCount = this.getDisplayCount(childrenLength), _this$getDisplayCount2 = (0, _slicedToArray2.default)(_this$getDisplayCount, 2), displayCount = _this$getDisplayCount2[0], shouldTruncate = _this$getDisplayCount2[1]; return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_ScrollGradient.default, { className: "".concat(namespace, "__scroller-container"), scrollElementClassName: "".concat(namespace, "__scroller"), color: scrollGradientColor, getScrollElementRef: this.setListContainer }, /*#__PURE__*/_react.default.createElement(List, (0, _extends2.default)({ className: (0, _classnames.default)(className, namespace) }, other), childrenArray.slice(0, displayCount), shouldTruncate && isExpanded && childrenArray.slice(displayCount))), shouldTruncate && /*#__PURE__*/_react.default.createElement(_Button.default, { className: (0, _classnames.default)(expandButtonClassName, "".concat(_namespace.carbonPrefix, "--link"), "".concat(namespace, "__expand-button")), iconDescription: "", size: "small", onClick: this.handleExpand }, getExpandButtonLabel(isExpanded, isExpanded ? childrenLength : displayCount, isExpanded ? 0 : childrenLength - displayCount))); } }]); }(_react.Component); TruncatedList.propTypes = { /** The type of list element to render. This could be a ul, ol, or a custom React component. (Optional) */ as: _propTypes.default.oneOfType([_propTypes.default.elementType, _propTypes.default.string]), /** Items to have in the list. */ children: _propTypes.default.node, /** Optional list class name. */ className: _propTypes.default.string, /** Number of items to display when the list is truncated and collapsed. */ collapsedItemLimit: _propTypes.default.number, /** Optional class name for expand button. */ expandButtonClassName: _propTypes.default.string, /** * Number of items to show when the list is truncated and expanded. All items are rendered when * the list is expanded, this prop is to limit the visual height of the list. */ expandedItemLimit: _propTypes.default.number, /** Function to compute the label for the expand toggle button. */ getExpandButtonLabel: _propTypes.default.func, /** Optional scroll gradient color. */ scrollGradientColor: _propTypes.default.string, /** Number of items allowed in the list before the list is truncated. */ truncateThreshold: _propTypes.default.number }; TruncatedList.defaultProps = { children: undefined, className: undefined, expandButtonClassName: undefined, as: 'ul', scrollGradientColor: _theme.default.uiBackground, getExpandButtonLabel: function getExpandButtonLabel() { return 'getExpandButtonLabel'; }, truncateThreshold: 10, collapsedItemLimit: 5, expandedItemLimit: 10 }; var _default = exports.default = TruncatedList;