UNPKG

@carbon/ibm-security

Version:

Carbon for Cloud & Cognitive IBM Security UI components

258 lines (255 loc) 14.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.namespace = exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); 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 _iconsReact = require("@carbon/icons-react"); var _requiredIfGivenPropIsTruthy = _interopRequireDefault(require("carbon-components-react/lib/prop-types/requiredIfGivenPropIsTruthy")); var _setupGetInstanceId = _interopRequireDefault(require("carbon-components-react/lib/tools/setupGetInstanceId")); var _classnames2 = _interopRequireDefault(require("classnames")); var _propTypes = _interopRequireWildcard(require("prop-types")); var _react = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _namespace = require("../../globals/namespace"); var defaultLabels = _interopRequireWildcard(require("../../globals/nls")); var _capabilities = require("../../globals/utils/capabilities"); var _focus = require("../../globals/utils/focus"); var _Button = _interopRequireDefault(require("../Button")); var _IconButton = _interopRequireDefault(require("../IconButton")); var _PanelContainer$propT; 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 ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } 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 Panel container. * @copyright IBM Security 2019 - 2021 */ /* eslint-disable no-useless-computed-key, react/require-default-props */ var namespace = exports.namespace = (0, _namespace.getComponentNamespace)('panel'); var getInstanceId = (0, _setupGetInstanceId.default)(); /** * Panel container component. * @param {Record<string, any>} props Panel container props. * @returns {PanelContainer} Panel container instance. */ var PanelContainer = exports.default = /*#__PURE__*/function (_Component) { function PanelContainer(props) { var _this; (0, _classCallCheck2.default)(this, PanelContainer); _this = _callSuper(this, PanelContainer, [props]); (0, _defineProperty2.default)(_this, "state", { bodyMargin: 0 }); /** * Retrieves the element to render the panel container in to via a portal. * @returns {HTMLElement} The element to render the panel container in to via a portal. */ (0, _defineProperty2.default)(_this, "getContainer", function () { if ((0, _capabilities.isClient)()) { var panels = document.getElementsByClassName(namespace); if (panels.length > 0) { return panels[0].parentNode; } } return null; }); (0, _defineProperty2.default)(_this, "panelInstanceId", "panel-".concat(getInstanceId())); (0, _defineProperty2.default)(_this, "panelTitleId", "".concat(namespace, "__title--").concat(_this.panelInstanceId)); (0, _defineProperty2.default)(_this, "panelSubtitleId", "".concat(namespace, "__subtitle--").concat(_this.panelInstanceId)); (0, _defineProperty2.default)(_this, "footer", /*#__PURE__*/(0, _react.createRef)()); (0, _defineProperty2.default)(_this, "header", /*#__PURE__*/(0, _react.createRef)()); /** * Handles the key press focus trap. * @param {SyntheticEvent} event The event fired when a key has been pressed while the panel container is in focus. */ (0, _defineProperty2.default)(_this, "handleKeyPress", function (event) { if (event.key === 'Tab') { (0, _focus.trapTabFocus)(_this.element, event); } else if (!_this.props.disableEscape && event.key === 'Escape') { _this.props.closeButton.onClick(); } }); (0, _defineProperty2.default)(_this, "renderPanelContainer", function (_ref) { var _ref$labels = _ref.labels, PANEL_CONTAINER_PRIMARY_BUTTON = _ref$labels.PANEL_CONTAINER_PRIMARY_BUTTON, PANEL_CONTAINER_SECONDARY_BUTTON = _ref$labels.PANEL_CONTAINER_SECONDARY_BUTTON, PANEL_CONTAINER_CLOSE_BUTTON = _ref$labels.PANEL_CONTAINER_CLOSE_BUTTON; var _this$props = _this.props, children = _this$props.children, closeButton = _this$props.closeButton, primaryButton = _this$props.primaryButton, renderFooter = _this$props.renderFooter, secondaryButton = _this$props.secondaryButton, subtitle = _this$props.subtitle, title = _this$props.title, hasScrollingContent = _this$props.hasScrollingContent; var hasFooter = renderFooter || primaryButton; var ariaLabel = _this.props['aria-label'] || title || subtitle; var getAriaLabelledBy = title || subtitle ? { 'aria-labelledby': title ? _this.panelTitleId : _this.panelSubtitleId } : {}; var hasScrollingContentProps = hasScrollingContent ? { tabIndex: 0, role: 'region', 'aria-label': ariaLabel } : {}; return /*#__PURE__*/_react.default.createElement("div", { role: "dialog", "aria-label": ariaLabel, "aria-modal": "true" }, /*#__PURE__*/_react.default.createElement("header", { ref: _this.header, className: "".concat(namespace, "__header") }, title && /*#__PURE__*/_react.default.createElement("div", { className: "".concat(namespace, "__header__container--title") }, /*#__PURE__*/_react.default.createElement("div", { id: _this.panelTitleId, className: "".concat(namespace, "__header--title") }, title), subtitle && /*#__PURE__*/_react.default.createElement("div", { id: _this.panelSubtitleId, className: "".concat(namespace, "__header--subtitle") }, subtitle)), /*#__PURE__*/_react.default.createElement(_IconButton.default, { id: closeButton.id, className: "".concat(namespace, "__button--close"), label: PANEL_CONTAINER_CLOSE_BUTTON, onClick: closeButton.onClick, renderIcon: closeButton.icon || _iconsReact.Close20, tooltip: false })), /*#__PURE__*/_react.default.createElement("section", (0, _extends2.default)({ className: (0, _classnames2.default)("".concat(namespace, "__body"), (0, _defineProperty2.default)({}, "".concat(namespace, "__body--footer"), hasFooter)), style: { marginTop: "".concat(_this.state.bodyMargin.top, "px"), marginBottom: "".concat(_this.state.bodyMargin.bottom, "px") } }, hasScrollingContentProps, getAriaLabelledBy), children), hasFooter && /*#__PURE__*/_react.default.createElement("div", { ref: _this.footer, className: "".concat(namespace, "__footer") }, renderFooter ? renderFooter() : /*#__PURE__*/_react.default.createElement(_react.Fragment, null, secondaryButton && /*#__PURE__*/_react.default.createElement(_Button.default, { id: secondaryButton.id, className: "".concat(namespace, "__footer__button ").concat(namespace, "__footer__button--secondary"), disabled: secondaryButton.isDisabled, iconDescription: secondaryButton.iconDescription, kind: "secondary", onClick: secondaryButton.onClick, renderIcon: secondaryButton.icon }, PANEL_CONTAINER_SECONDARY_BUTTON), /*#__PURE__*/_react.default.createElement(_Button.default, { id: primaryButton.id, className: "".concat(namespace, "__footer__button"), disabled: primaryButton.isDisabled, iconDescription: primaryButton.iconDescription, onClick: primaryButton.onClick, renderIcon: primaryButton.icon }, PANEL_CONTAINER_PRIMARY_BUTTON)))); }); if ((0, _capabilities.isClient)()) { _this.container = _this.getContainer(); _this.containerClass = "".concat(namespace, "__container"); _this.element = document.createElement('section'); _this.element.classList.add(namespace); _this.previousFocus = document.activeElement; _this.rootNode = _this.props.rootNode; var className = _this.props.className; if (className) { _this.element.classList.add(className); } } return _this; } (0, _inherits2.default)(PanelContainer, _Component); return (0, _createClass2.default)(PanelContainer, [{ key: "componentDidMount", value: function componentDidMount() { if ((0, _capabilities.isClient)()) { if (!this.container) { this.container = document.createElement('div'); this.rootNode.appendChild(this.container); } this.container.appendChild(this.element); if (this.container.childElementCount === 1) { this.rootNode.classList.toggle(this.containerClass); } (0, _focus.focusFirstElement)(this.element); this.element.addEventListener('keydown', this.handleKeyPress); this.setBodyMargin(); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if ((0, _capabilities.isClient)()) { this.container.removeChild(this.element); if (this.container.childElementCount === 0) { this.rootNode.classList.toggle(this.containerClass); this.rootNode.removeChild(this.container); } this.element.removeEventListener('keydown', this.handleKeyPress); this.previousFocus.focus(); } } }, { key: "setBodyMargin", value: /** * Sets the body margin to match the height of the header for fixed scrolling. */ function setBodyMargin() { var footer = this.footer.current; this.setState({ bodyMargin: { top: this.header.current.clientHeight, bottom: footer && footer.clientHeight } }); } }, { key: "render", value: function render() { var _this$props2 = this.props, closeButton = _this$props2.closeButton, primaryButton = _this$props2.primaryButton, secondaryButton = _this$props2.secondaryButton, labels = _this$props2.labels; var componentLabels = _objectSpread(_objectSpread(_objectSpread({}, defaultLabels.labels), labels), defaultLabels.filterFalsey({ PANEL_CONTAINER_PRIMARY_BUTTON: primaryButton && primaryButton.label || '', PANEL_CONTAINER_SECONDARY_BUTTON: secondaryButton && secondaryButton.label || '', PANEL_CONTAINER_CLOSE_BUTTON: closeButton && closeButton.label || '' })); return (0, _capabilities.isClient)() && /*#__PURE__*/(0, _reactDom.createPortal)(this.renderPanelContainer({ labels: componentLabels }), this.element); } }]); }(_react.Component); var buttonType = _propTypes.default.shape({ id: _propTypes.default.string, onClick: _propTypes.default.func, label: _propTypes.default.string, isDisabled: _propTypes.default.bool, icon: _propTypes.default.object, iconDescription: _propTypes.default.string }); PanelContainer.propTypes = (_PanelContainer$propT = {}, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)(_PanelContainer$propT, 'aria-label', (0, _requiredIfGivenPropIsTruthy.default)('hasScrollingContent', _propTypes.default.string)), "children", _propTypes.default.node), "className", _propTypes.default.string), "closeButton", buttonType.isRequired), "disableEscape", _propTypes.default.bool), "hasScrollingContent", _propTypes.default.bool), "labels", defaultLabels.propType), "primaryButton", buttonType), "renderFooter", _propTypes.func), "rootNode", (0, _capabilities.isNode)() ? _propTypes.default.instanceOf(Node) : _propTypes.default.any), (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)(_PanelContainer$propT, "secondaryButton", buttonType), "subtitle", _propTypes.default.node), "title", _propTypes.default.node)); PanelContainer.defaultProps = { children: null, className: null, disableEscape: false, primaryButton: null, secondaryButton: undefined, subtitle: undefined, title: undefined, renderFooter: null, rootNode: (0, _capabilities.isNode)() ? document.body : undefined, labels: {}, hasScrollingContent: false }; /* eslint-enable */