UNPKG

@carbon/ibm-products

Version:

Carbon for IBM Products

204 lines (193 loc) 7.18 kB
/** * 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 icons = require('@carbon/react/icons'); var React = require('react'); var index = require('../../_virtual/index.js'); var cx = require('classnames'); var devtools = require('../../global/js/utils/devtools.js'); var settings = require('../../settings.js'); var index$1 = require('./hooks/index.js'); var usePrefersReducedMotion = require('../../global/js/hooks/usePrefersReducedMotion.js'); // The block part of our conventional BEM class names (blockClass__E--M). const componentName = 'WebTerminal'; const blockClass = `${settings.pkg.prefix}--web-terminal`; // Default values for props const defaults = { actions: Object.freeze([]), documentationLinks: Object.freeze([]), documentationLinksIconDescription: 'Show documentation links', isInitiallyOpen: false, webTerminalAriaLabel: 'Web terminal header' }; /** * The `WebTerminal` is prompted by the user and is persistent until dismissed. The purpose of a web terminal is to provide users with the ability to type commands manually instead of using the GUI. */ exports.WebTerminal = /*#__PURE__*/React.forwardRef((_ref, ref) => { let { // The component props, in alphabetical order (for consistency). actions = defaults.actions, children, className, closeIconDescription, documentationLinks = defaults.documentationLinks, documentationLinksIconDescription = defaults.documentationLinksIconDescription, isInitiallyOpen = defaults.isInitiallyOpen, webTerminalAriaLabel = defaults.webTerminalAriaLabel, // Collect any other property values passed in. ...rest } = _ref; const localRef = React.useRef(null); const webTerminalRef = ref ?? localRef; const { open, closeWebTerminal, openWebTerminal } = index$1.useWebTerminal(); const [shouldRender, setRender] = React.useState(open); const shouldReduceMotion = usePrefersReducedMotion.usePrefersReducedMotion(); const showDocumentationLinks = React.useMemo(() => documentationLinks.length > 0, [documentationLinks]); React.useEffect(() => { if (open) { setRender(true); } }, [open]); /** On render, check if user want's the web terminal to be open by default */ React.useEffect(() => { if (isInitiallyOpen) { openWebTerminal?.(); } }, []); // eslint-disable-line /** When the web terminal slide in animation is complete, sets render to false. */ const onAnimationEnd = () => { if (!open) { setRender(false); } }; const handleCloseTerminal = () => { /** If the user prefers reduced motion, we have to manually set render to false because onAnimationEnd will never be called. */ if (shouldReduceMotion) { setRender(false); } closeWebTerminal?.(); }; return shouldRender ? /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({}, rest, devtools.getDevtoolsProps(componentName), { ref: webTerminalRef, className: cx([blockClass, className, { [`${blockClass}--open`]: open, [`${blockClass}--closed`]: !open }]), onAnimationEnd: onAnimationEnd }), /*#__PURE__*/React.createElement("header", { "aria-label": webTerminalAriaLabel, className: `${blockClass}__bar` }, /*#__PURE__*/React.createElement("div", { className: `${blockClass}__actions` }, showDocumentationLinks && /*#__PURE__*/React.createElement(react.OverflowMenu, { renderIcon: props => /*#__PURE__*/React.createElement(icons.Help, _rollupPluginBabelHelpers.extends({ size: 16 }, props)), iconDescription: documentationLinksIconDescription, "aria-label": documentationLinksIconDescription, menuOptionsClass: `${blockClass}__documentation-overflow`, size: "lg" }, documentationLinks.map((_ref2, i) => { let { ...rest } = _ref2; return /*#__PURE__*/React.createElement(react.OverflowMenuItem, _rollupPluginBabelHelpers.extends({ key: i }, rest)); })), actions.map(_ref3 => { let { renderIcon, onClick, iconDescription } = _ref3; return /*#__PURE__*/React.createElement(react.Button, { key: iconDescription, hasIconOnly: true, renderIcon: renderIcon, onClick: onClick, iconDescription: iconDescription, kind: "ghost", "aria-label": iconDescription }); })), /*#__PURE__*/React.createElement(react.Button, { hasIconOnly: true, renderIcon: props => /*#__PURE__*/React.createElement(icons.Close, _rollupPluginBabelHelpers.extends({ size: 16 }, props)), kind: "ghost", iconDescription: closeIconDescription, onClick: handleCloseTerminal, onAnimationEnd: event => event.stopPropagation() })), /*#__PURE__*/React.createElement(react.Theme, { theme: "g100" }, /*#__PURE__*/React.createElement("div", { className: `${blockClass}__body` }, children))) : null; }); // Return a placeholder if not released and not enabled by feature flag exports.WebTerminal = settings.pkg.checkComponentEnabled(exports.WebTerminal, componentName); // The display name of the component, used by React. Note that displayName // is used in preference to relying on function.name. exports.WebTerminal.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.WebTerminal.propTypes = { /** * An array of actions to be displayed in the web terminal header bar */ /**@ts-ignore */ actions: index.default.arrayOf(index.default.shape({ renderIcon: index.default.func.isRequired, onClick: index.default.func.isRequired, iconDescription: index.default.string.isRequired })), /** * Provide your own terminal component as children to show up in the web terminal */ children: index.default.oneOfType([index.default.arrayOf(index.default.node), index.default.node]).isRequired, /** * Custom classname for additional styling of the web terminal */ className: index.default.string, /** * Icon description for the close button */ closeIconDescription: index.default.string.isRequired, /** * Array of objects for each documentation link. Each documentation link uses the prop types of OverflowMenuItems. See more: https://react.carbondesignsystem.com/?path=/docs/components-overflowmenu--default */ /**@ts-ignore */ documentationLinks: index.default.arrayOf(index.default.shape({ ...react.OverflowMenuItem.propTypes })), /** * Description for the documentation link overflow menu tooltip */ documentationLinksIconDescription: index.default.string, /** * Optionally pass if the web terminal should be open by default */ isInitiallyOpen: index.default.bool, /** * Specifies aria label for Web terminal */ webTerminalAriaLabel: index.default.string };