@carbon/ibm-products
Version:
Carbon for IBM Products
185 lines (177 loc) • 6.81 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.
*/
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
import { unstable_FeatureFlags, ComposedModal, ModalHeader, ModalBody, Theme, ModalFooter } from '@carbon/react';
import React__default, { useRef, useEffect } from 'react';
import PropTypes from '../../_virtual/index.js';
import cx from 'classnames';
import { getDevtoolsProps } from '../../global/js/utils/devtools.js';
import { useFocus } from '../../global/js/hooks/useFocus.js';
import { pkg } from '../../settings.js';
import { usePortalTarget } from '../../global/js/hooks/usePortalTarget.js';
import uuidv4 from '../../global/js/utils/uuidv4.js';
// The block part of our conventional BEM class names (blockClass__E--M).
const blockClass = `${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.
*/
let AboutModal = /*#__PURE__*/React__default.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 = useRef(null);
const localRef = useRef(undefined);
const modalRef = ref || localRef;
const contentRef = useRef(null);
const contentId = uuidv4();
const renderPortalUse = usePortalTarget(portalTargetIn);
const {
claimFocus
} = 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
useEffect(() => {
bodyRef.current = contentRef.current?.parentElement;
}, [bodyRef]);
useEffect(() => {
if (open) {
claimFocus();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [modalRef, open]);
return renderPortalUse(/*#__PURE__*/React__default.createElement(unstable_FeatureFlags, {
enableExperimentalFocusWrapWithoutSentinels: true
}, /*#__PURE__*/React__default.createElement(ComposedModal, _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
}, getDevtoolsProps(componentName)), /*#__PURE__*/React__default.createElement("div", {
className: `${blockClass}__logo`
}, logo), /*#__PURE__*/React__default.createElement(ModalHeader, {
className: `${blockClass}__header`,
closeModal: onClose,
iconDescription: closeIconDescription,
label: title,
labelClassName: `${blockClass}__title`
}), /*#__PURE__*/React__default.createElement(ModalBody, {
className: `${blockClass}__body`
}, /*#__PURE__*/React__default.createElement("div", {
className: `${blockClass}__body-content`,
ref: contentRef,
id: contentId
}, /*#__PURE__*/React__default.createElement("div", {
className: `${blockClass}__version`
}, version), links && links.length > 0 && /*#__PURE__*/React__default.createElement("div", {
className: `${blockClass}__links-container`
}, links.map((link, i) => /*#__PURE__*/React__default.createElement(React__default.Fragment, {
key: i
}, link))), content && /*#__PURE__*/React__default.createElement("p", {
className: `${blockClass}__content`
}, content), copyrightText && /*#__PURE__*/React__default.createElement("p", {
className: `${blockClass}__copyright-text`
}, copyrightText))), additionalInfo && /*#__PURE__*/React__default.createElement(Theme, {
theme: "g100"
}, /*#__PURE__*/React__default.createElement(ModalFooter, {
className: `${blockClass}__footer`
}, additionalInfo)))));
});
// Return a placeholder if not released and not enabled by feature flag
AboutModal = pkg.checkComponentEnabled(AboutModal, componentName);
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.
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: PropTypes.node,
/**
* Provide an optional class to be applied to the modal root node.
*/
className: PropTypes.string,
/**
* The accessibility title for the close icon.
*/
closeIconDescription: PropTypes.string.isRequired,
/**
* Subhead text providing any relevant product disclaimers including
* legal information (optional)
*/
content: PropTypes.node,
/**
* Trademark and copyright information. Displays first year of
* product release to current year.
*/
copyrightText: PropTypes.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: PropTypes.arrayOf(PropTypes.element),
/**
* A visual symbol used to represent the product.
*/
logo: PropTypes.node.isRequired,
/**
* Specifies aria label for AboutModal
*/
modalAriaLabel: PropTypes.string,
/**
* Specifies an optional handler which is called when the AboutModal
* is closed. Returning `false` prevents the AboutModal from closing.
*/
onClose: PropTypes.func,
/**
* Specifies whether the AboutModal is open or not.
*/
open: PropTypes.bool,
/**
* The DOM node the tearsheet should be rendered within. Defaults to document.body.
*/
portalTarget: PropTypes.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: PropTypes.node.isRequired,
/**
* Text that provides information on the version number of your product.
*/
version: PropTypes.string.isRequired
};
export { AboutModal };