@carbon/ibm-products
Version:
Carbon for IBM Products
185 lines (177 loc) • 6.8 kB
JavaScript
/**
* Copyright IBM Corp. 2020, 2025
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
var react = require('@carbon/react');
var React = require('react');
var index = require('../../_virtual/index.js');
var cx = require('classnames');
var devtools = require('../../global/js/utils/devtools.js');
var useFocus = require('../../global/js/hooks/useFocus.js');
var settings = require('../../settings.js');
var usePortalTarget = require('../../global/js/hooks/usePortalTarget.js');
var uuidv4 = require('../../global/js/utils/uuidv4.js');
// The block part of our conventional BEM class names (blockClass__E--M).
const blockClass = `${settings.pkg.prefix}--about-modal`;
const componentName = 'AboutModal';
// NOTE: the component SCSS is not imported here: it is rolled up separately.
/**
* The `AboutModal` component provides a way to communicate product information
* to users. It is triggered by a user’s action, appears on top of the main
* page content, and is persistent until dismissed. The purpose of this modal
* should be immediately apparent to the user, with a clear and obvious path
* to completion.
*/
exports.AboutModal = /*#__PURE__*/React.forwardRef((_ref, ref) => {
let {
additionalInfo,
className,
closeIconDescription,
copyrightText,
content,
links,
logo,
modalAriaLabel,
onClose,
open,
portalTarget: portalTargetIn,
title,
version,
// Collect any other property values passed in.
...rest
} = _ref;
const bodyRef = React.useRef(null);
const localRef = React.useRef(undefined);
const modalRef = ref || localRef;
const contentRef = React.useRef(null);
const contentId = uuidv4.default();
const renderPortalUse = usePortalTarget.usePortalTarget(portalTargetIn);
const {
claimFocus
} = useFocus.useFocus(modalRef);
// We can't add a ref directly to the ModalBody, so track it in a ref
// as the parent of the current bodyRef element
React.useEffect(() => {
bodyRef.current = contentRef.current?.parentElement;
}, [bodyRef]);
React.useEffect(() => {
if (open) {
claimFocus();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [modalRef, open]);
return renderPortalUse(/*#__PURE__*/React.createElement(react.unstable_FeatureFlags, {
enableExperimentalFocusWrapWithoutSentinels: true
}, /*#__PURE__*/React.createElement(react.ComposedModal, _rollupPluginBabelHelpers.extends({}, rest, {
className: cx(blockClass,
// Apply the block class to the main HTML element
className // Apply any supplied class names to the main HTML element.
),
"aria-label": modalAriaLabel,
ref: modalRef,
onClose,
open
}, devtools.getDevtoolsProps(componentName)), /*#__PURE__*/React.createElement("div", {
className: `${blockClass}__logo`
}, logo), /*#__PURE__*/React.createElement(react.ModalHeader, {
className: `${blockClass}__header`,
closeModal: onClose,
iconDescription: closeIconDescription,
label: title,
labelClassName: `${blockClass}__title`
}), /*#__PURE__*/React.createElement(react.ModalBody, {
className: `${blockClass}__body`
}, /*#__PURE__*/React.createElement("div", {
className: `${blockClass}__body-content`,
ref: contentRef,
id: contentId
}, /*#__PURE__*/React.createElement("div", {
className: `${blockClass}__version`
}, version), links && links.length > 0 && /*#__PURE__*/React.createElement("div", {
className: `${blockClass}__links-container`
}, links.map((link, i) => /*#__PURE__*/React.createElement(React.Fragment, {
key: i
}, link))), content && /*#__PURE__*/React.createElement("p", {
className: `${blockClass}__content`
}, content), copyrightText && /*#__PURE__*/React.createElement("p", {
className: `${blockClass}__copyright-text`
}, copyrightText))), additionalInfo && /*#__PURE__*/React.createElement(react.Theme, {
theme: "g100"
}, /*#__PURE__*/React.createElement(react.ModalFooter, {
className: `${blockClass}__footer`
}, additionalInfo)))));
});
// Return a placeholder if not released and not enabled by feature flag
exports.AboutModal = settings.pkg.checkComponentEnabled(exports.AboutModal, componentName);
exports.AboutModal.displayName = componentName;
// The types and DocGen commentary for the component props,
// in alphabetical order (for consistency).
// See https://www.npmjs.com/package/prop-types#usage.
exports.AboutModal.propTypes = {
/**
* If you are legally required to display logos of technologies used
* to build your product you can provide this in the additionalInfo.
* Additional information will be displayed in the footer.
*/
additionalInfo: index.default.node,
/**
* Provide an optional class to be applied to the modal root node.
*/
className: index.default.string,
/**
* The accessibility title for the close icon.
*/
closeIconDescription: index.default.string.isRequired,
/**
* Subhead text providing any relevant product disclaimers including
* legal information (optional)
*/
content: index.default.node,
/**
* Trademark and copyright information. Displays first year of
* product release to current year.
*/
copyrightText: index.default.string.isRequired,
/**
* An array of Carbon `Link` component if there are additional information
* to call out within the card. The about modal should be used to display
* the product information and not where users go to find help (optional)
*/
links: index.default.arrayOf(index.default.element),
/**
* A visual symbol used to represent the product.
*/
logo: index.default.node.isRequired,
/**
* Specifies aria label for AboutModal
*/
modalAriaLabel: index.default.string,
/**
* Specifies an optional handler which is called when the AboutModal
* is closed. Returning `false` prevents the AboutModal from closing.
*/
onClose: index.default.func,
/**
* Specifies whether the AboutModal is open or not.
*/
open: index.default.bool,
/**
* The DOM node the tearsheet should be rendered within. Defaults to document.body.
*/
portalTarget: index.default.node,
/**
* Header text that provides the product name. The IBM Services logo
* consists of two discrete, but required, elements: the iconic
* IBM 8-bar logo represented alongside the IBM Services logotype.
* Please follow these guidelines to ensure proper execution.
*/
title: index.default.node.isRequired,
/**
* Text that provides information on the version number of your product.
*/
version: index.default.string.isRequired
};