@carbon/ibm-products
Version:
Carbon for IBM Products
161 lines (159 loc) • 6.71 kB
JavaScript
/**
* Copyright IBM Corp. 2020, 2026
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
const require_runtime = require("../../_virtual/_rolldown/runtime.js");
const require_index = require("../../node_modules/classnames/index.js");
const require_settings = require("../../settings.js");
const require_usePrefersReducedMotion = require("../../global/js/hooks/usePrefersReducedMotion.js");
const require_devtools = require("../../global/js/utils/devtools.js");
const require_index$1 = require("./hooks/index.js");
let react = require("react");
react = require_runtime.__toESM(react);
let prop_types = require("prop-types");
prop_types = require_runtime.__toESM(prop_types);
let _carbon_react = require("@carbon/react");
let _carbon_react_icons = require("@carbon/react/icons");
//#region src/components/WebTerminal/WebTerminal.tsx
/**
* Copyright IBM Corp. 2020, 2022
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
var import_classnames = /* @__PURE__ */ require_runtime.__toESM(require_index.default);
const componentName = "WebTerminal";
const blockClass = `${require_settings.pkg.prefix}--web-terminal`;
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.
*/
const WebTerminal = react.default.forwardRef(({ actions = defaults.actions, children, className, closeIconDescription, documentationLinks = defaults.documentationLinks, documentationLinksIconDescription = defaults.documentationLinksIconDescription, isInitiallyOpen = defaults.isInitiallyOpen, webTerminalAriaLabel = defaults.webTerminalAriaLabel, ...rest }, ref) => {
const localRef = (0, react.useRef)(null);
const webTerminalRef = ref ?? localRef;
const { open, closeWebTerminal, openWebTerminal } = require_index$1.useWebTerminal();
const [shouldRender, setRender] = (0, react.useState)(open);
const shouldReduceMotion = require_usePrefersReducedMotion.usePrefersReducedMotion();
const showDocumentationLinks = (0, react.useMemo)(() => documentationLinks.length > 0, [documentationLinks]);
(0, react.useEffect)(() => {
if (open) setRender(true);
}, [open]);
/**
On render, check if user want's the web terminal to be open by default
*/
(0, react.useEffect)(() => {
if (isInitiallyOpen) openWebTerminal?.();
}, []);
/**
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.default.createElement("div", {
...rest,
...require_devtools.getDevtoolsProps(componentName),
ref: webTerminalRef,
className: (0, import_classnames.default)([
blockClass,
className,
{
[`${blockClass}--open`]: open,
[`${blockClass}--closed`]: !open
}
]),
onAnimationEnd
}, /* @__PURE__ */ react.default.createElement("header", {
"aria-label": webTerminalAriaLabel,
className: `${blockClass}__bar`
}, /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__actions` }, showDocumentationLinks && /* @__PURE__ */ react.default.createElement(_carbon_react.OverflowMenu, {
renderIcon: (props) => /* @__PURE__ */ react.default.createElement(_carbon_react_icons.Help, {
size: 16,
...props
}),
iconDescription: documentationLinksIconDescription,
"aria-label": documentationLinksIconDescription,
menuOptionsClass: `${blockClass}__documentation-overflow`,
size: "lg"
}, documentationLinks.map(({ ...rest }, i) => /* @__PURE__ */ react.default.createElement(_carbon_react.OverflowMenuItem, {
key: i,
...rest
}))), actions.map(({ renderIcon, onClick, iconDescription }) => /* @__PURE__ */ react.default.createElement(_carbon_react.Button, {
key: iconDescription,
hasIconOnly: true,
renderIcon,
onClick,
iconDescription,
kind: "ghost",
"aria-label": iconDescription
}))), /* @__PURE__ */ react.default.createElement(_carbon_react.Button, {
hasIconOnly: true,
renderIcon: (props) => /* @__PURE__ */ react.default.createElement(_carbon_react_icons.Close, {
size: 16,
...props
}),
kind: "ghost",
iconDescription: closeIconDescription,
onClick: handleCloseTerminal,
onAnimationEnd: (event) => event.stopPropagation()
})), /* @__PURE__ */ react.default.createElement(_carbon_react.Theme, { theme: "g100" }, /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__body` }, children))) : null;
});
WebTerminal.displayName = componentName;
WebTerminal.propTypes = {
/**
* An array of actions to be displayed in the web terminal header bar
*/
/**@ts-ignore */
actions: prop_types.default.arrayOf(prop_types.default.shape({
renderIcon: prop_types.default.func.isRequired,
onClick: prop_types.default.func.isRequired,
iconDescription: prop_types.default.string.isRequired
})),
/**
* Provide your own terminal component as children to show up in the web terminal
*/
children: prop_types.default.oneOfType([prop_types.default.arrayOf(prop_types.default.node), prop_types.default.node]).isRequired,
/**
* Custom classname for additional styling of the web terminal
*/
className: prop_types.default.string,
/**
* Icon description for the close button
*/
closeIconDescription: prop_types.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: prop_types.default.arrayOf(prop_types.default.shape({ ..._carbon_react.OverflowMenuItem.propTypes })),
/**
* Description for the documentation link overflow menu tooltip
*/
documentationLinksIconDescription: prop_types.default.string,
/**
* Optionally pass if the web terminal should be open by default
*/
isInitiallyOpen: prop_types.default.bool,
/**
* Specifies aria label for Web terminal
*/
webTerminalAriaLabel: prop_types.default.string
};
//#endregion
exports.WebTerminal = WebTerminal;