@carbon/ibm-security
Version:
Carbon for Cloud & Cognitive IBM Security UI components
258 lines (255 loc) • 14.8 kB
JavaScript
"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 */