@carbon/ibm-security
Version:
Carbon for Cloud & Cognitive IBM Security UI components
207 lines (203 loc) • 10.6 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
var _PanelV2$propTypes;
var _excluded = ["children", "className", "closeButton", "focusTrap", "focusTrapOptions", "hasScrollingContent", "isOpen", "labels", "onClose", "primaryButton", "renderFooter", "rootNode", "secondaryButton", "stopPropagation", "stopPropagationEvents", "subtitle", "title"];
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) { _defineProperty(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; }
/**
* @file Panel v2.
* @copyright IBM Security 2019 - 2021
*/
/* eslint-disable no-useless-computed-key, react/require-default-props */
import { Close20 } from '@carbon/icons-react';
import deprecate from 'carbon-components-react/es/prop-types/deprecate';
import requiredIfGivenPropIsTruthy from 'carbon-components-react/es/prop-types/requiredIfGivenPropIsTruthy';
import setupGetInstanceId from 'carbon-components-react/es/tools/setupGetInstanceId';
import classnames from 'classnames';
import PropTypes from 'prop-types';
import React, { useCallback, useState } from 'react';
import { getComponentNamespace } from '../../globals/namespace';
import * as defaultLabels from '../../globals/nls';
import { isNode } from '../../globals/utils/capabilities';
import Button from '../Button';
import IconButton from '../IconButton';
import Portal, { PORTAL_EVENTS } from '../Portal';
import Transition from '../Transition';
export var namespace = getComponentNamespace('panel--v2');
var getInstanceId = setupGetInstanceId();
/**
* Panel v2 container component.
* @param {Record<string, any>} props Panel v2 container props.
* @returns {PanelV2} Panel v2 container instance.
*/
function PanelV2(_ref) {
var children = _ref.children,
className = _ref.className,
closeButton = _ref.closeButton,
focusTrap = _ref.focusTrap,
focusTrapOptions = _ref.focusTrapOptions,
hasScrollingContent = _ref.hasScrollingContent,
isOpen = _ref.isOpen,
labels = _ref.labels,
onClose = _ref.onClose,
primaryButton = _ref.primaryButton,
renderFooter = _ref.renderFooter,
rootNode = _ref.rootNode,
secondaryButton = _ref.secondaryButton,
stopPropagation = _ref.stopPropagation,
stopPropagationEvents = _ref.stopPropagationEvents,
subtitle = _ref.subtitle,
title = _ref.title,
other = _objectWithoutProperties(_ref, _excluded);
var _useState = useState(0),
_useState2 = _slicedToArray(_useState, 2),
bodyMarginTop = _useState2[0],
setBodyMarginTop = _useState2[1];
var _useState3 = useState(0),
_useState4 = _slicedToArray(_useState3, 2),
bodyMarginBottom = _useState4[0],
setBodyMarginBottom = _useState4[1];
var panelInstanceId = "panel-".concat(getInstanceId());
var panelTitleId = "".concat(namespace, "__title--").concat(panelInstanceId);
var panelSubtitleId = "".concat(namespace, "__subtitle--").concat(panelInstanceId);
var footerRef = useCallback(function (node) {
// Sets the body margin to match the height of the footer for fixed scrolling.
setBodyMarginBottom(node ? node.clientHeight : 0);
}, []);
var headerRef = useCallback(function (node) {
// Sets the body margin to match the height of the header for fixed scrolling.
setBodyMarginTop(node ? node.clientHeight : 0);
}, []);
var handleKeyDown = function handleKeyDown(event) {
if (isOpen && event.which === 27) {
onClose();
}
};
var renderPanel = function renderPanel(_ref2) {
var _ref2$labels = _ref2.labels,
PANEL_CONTAINER_PRIMARY_BUTTON = _ref2$labels.PANEL_CONTAINER_PRIMARY_BUTTON,
PANEL_CONTAINER_SECONDARY_BUTTON = _ref2$labels.PANEL_CONTAINER_SECONDARY_BUTTON,
PANEL_CONTAINER_CLOSE_BUTTON = _ref2$labels.PANEL_CONTAINER_CLOSE_BUTTON;
var hasFooter = renderFooter || primaryButton;
var ariaLabel = other['aria-label'] || title || subtitle;
var getAriaLabelledBy = title || subtitle ? {
'aria-labelledby': title ? panelTitleId : panelSubtitleId
} : {};
var hasScrollingContentProps = hasScrollingContent ? {
tabIndex: 0,
role: 'region',
'aria-label': ariaLabel
} : {};
return /*#__PURE__*/React.createElement(Transition, {
className: namespace
}, isOpen && /*#__PURE__*/React.createElement(Portal, {
focusTrap: focusTrap,
focusTrapOptions: focusTrapOptions,
overlayOptions: {
onClick: onClose
},
rootNode: rootNode,
stopPropagation: stopPropagation,
stopPropagationEvents: stopPropagationEvents
}, /*#__PURE__*/React.createElement("section", {
className: classnames(namespace, className),
role: "dialog",
"aria-label": ariaLabel,
"aria-modal": "true",
onKeyDown: handleKeyDown,
tabIndex: -1
}, /*#__PURE__*/React.createElement("header", {
ref: headerRef,
className: "".concat(namespace, "__header")
}, /*#__PURE__*/React.createElement(IconButton, {
id: closeButton.id,
className: "".concat(namespace, "__button--close"),
label: PANEL_CONTAINER_CLOSE_BUTTON,
onClick: closeButton.onClick || onClose,
renderIcon: closeButton.icon || Close20,
tooltip: false
}), title && /*#__PURE__*/React.createElement("div", {
className: "".concat(namespace, "__header__container--title")
}, typeof title === 'string' ? /*#__PURE__*/React.createElement("h2", {
id: panelTitleId,
className: "".concat(namespace, "__header--title")
}, title) : /*#__PURE__*/React.createElement("div", {
id: panelTitleId,
className: "".concat(namespace, "__header--title")
}, title), subtitle && /*#__PURE__*/React.createElement("div", {
id: panelSubtitleId,
className: "".concat(namespace, "__header--subtitle")
}, subtitle))), /*#__PURE__*/React.createElement("section", _extends({
className: classnames("".concat(namespace, "__body"), _defineProperty({}, "".concat(namespace, "__body--footer"), renderFooter)),
style: {
marginTop: "".concat(bodyMarginTop, "px"),
marginBottom: "".concat(bodyMarginBottom, "px")
}
}, hasScrollingContentProps, getAriaLabelledBy), children), hasFooter && /*#__PURE__*/React.createElement("footer", {
ref: footerRef,
className: "".concat(namespace, "__footer")
}, renderFooter ? renderFooter() : /*#__PURE__*/React.createElement(React.Fragment, null, secondaryButton && /*#__PURE__*/React.createElement(Button, {
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.createElement(Button, {
id: primaryButton.id,
className: "".concat(namespace, "__footer__button"),
disabled: primaryButton.isDisabled,
iconDescription: primaryButton.iconDescription,
onClick: primaryButton.onClick,
renderIcon: primaryButton.icon
}, PANEL_CONTAINER_PRIMARY_BUTTON))))));
};
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 renderPanel({
labels: componentLabels
});
}
var buttonType = PropTypes.shape({
id: PropTypes.string,
onClick: PropTypes.func,
label: PropTypes.string,
isDisabled: PropTypes.bool,
icon: PropTypes.object,
iconDescription: PropTypes.string
});
PanelV2.propTypes = (_PanelV2$propTypes = {}, _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_PanelV2$propTypes, 'aria-label', requiredIfGivenPropIsTruthy('hasScrollingContent', PropTypes.string)), "children", PropTypes.node), "className", PropTypes.string), "closeButton", PropTypes.shape({
id: PropTypes.string,
onClick: PropTypes.func,
label: PropTypes.string,
isDisabled: PropTypes.bool,
icon: PropTypes.object,
iconDescription: PropTypes.string
})), "focusTrap", PropTypes.bool), "focusTrapOptions", Portal.propTypes.focusTrapOptions), "hasScrollingContent", PropTypes.bool), "isOpen", PropTypes.bool), "labels", defaultLabels.propType), "onClose", PropTypes.func), _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_PanelV2$propTypes, "primaryButton", deprecate(buttonType, "\nThe prop `primaryButton` for PanelV2 has been deprecated in favor of `renderFooter`.")), "renderFooter", PropTypes.func), "rootNode", isNode() ? PropTypes.instanceOf(Node) : PropTypes.any), "secondaryButton", deprecate(buttonType, "\nThe prop `secondaryButton` for PanelV2 has been deprecated in favor of `renderFooter`.")), "stopPropagation", PropTypes.bool), "stopPropagationEvents", PropTypes.arrayOf(PropTypes.oneOf(PORTAL_EVENTS))), "subtitle", PropTypes.node), "title", PropTypes.node));
PanelV2.defaultProps = {
children: null,
className: null,
closeButton: undefined,
focusTrap: true,
focusTrapOptions: Portal.defaultProps.focusTrapOptions,
isOpen: true,
labels: {},
primaryButton: undefined,
renderFooter: null,
rootNode: undefined,
secondaryButton: undefined,
stopPropagation: false,
stopPropagationEvents: undefined,
subtitle: undefined,
title: undefined,
hasScrollingContent: false,
onClose: function onClose() {}
};
/* eslint-enable */
export default PanelV2;