UNPKG

@carbon/react

Version:

React components for the Carbon Design System

230 lines (228 loc) 9.17 kB
/** * Copyright IBM Corp. 2016, 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_usePrefix = require("../../internal/usePrefix.js"); const require_useId = require("../../internal/useId.js"); const require_deprecate = require("../../prop-types/deprecate.js"); const require_deprecateValuesWithin = require("../../prop-types/deprecateValuesWithin.js"); const require_mapPopoverAlign = require("../../tools/mapPopoverAlign.js"); const require_index = require("../Button/index.js"); const require_useResizeObserver = require("../../internal/useResizeObserver.js"); const require_index$1 = require("../Copy/index.js"); const require_index$2 = require("../CopyButton/index.js"); let classnames = require("classnames"); classnames = require_runtime.__toESM(classnames); let react = require("react"); react = require_runtime.__toESM(react); let prop_types = require("prop-types"); prop_types = require_runtime.__toESM(prop_types); let react_jsx_runtime = require("react/jsx-runtime"); let _carbon_icons_react = require("@carbon/icons-react"); let copy_to_clipboard = require("copy-to-clipboard"); copy_to_clipboard = require_runtime.__toESM(copy_to_clipboard); //#region src/components/CodeSnippet/CodeSnippet.tsx /** * Copyright IBM Corp. 2016, 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. */ const rowHeightInPixels = 16; const defaultMaxCollapsedNumberOfRows = 15; const defaultMaxExpandedNumberOfRows = 0; const defaultMinCollapsedNumberOfRows = 3; const defaultMinExpandedNumberOfRows = 16; function CodeSnippet({ align = "bottom", autoAlign = false, className, type = "single", children, disabled, feedback, feedbackTimeout, onClick, ["aria-label"]: ariaLabel = "Copy to clipboard", ariaLabel: deprecatedAriaLabel, copyText, copyButtonDescription, light, showMoreText = "Show more", showLessText = "Show less", hideCopyButton, wrapText = false, maxCollapsedNumberOfRows = defaultMaxCollapsedNumberOfRows, maxExpandedNumberOfRows = defaultMaxExpandedNumberOfRows, minCollapsedNumberOfRows = defaultMinCollapsedNumberOfRows, minExpandedNumberOfRows = defaultMinExpandedNumberOfRows, ...rest }) { const [expandedCode, setExpandedCode] = (0, react.useState)(false); const [shouldShowMoreLessBtn, setShouldShowMoreLessBtn] = (0, react.useState)(false); const { current: uid } = (0, react.useRef)(require_useId.useId()); const codeContentRef = (0, react.useRef)(null); const codeContainerRef = (0, react.useRef)(null); const innerCodeRef = (0, react.useRef)(null); const getCodeRef = (0, react.useCallback)(() => { if (type === "single") return codeContainerRef; if (type === "multi") return codeContentRef; else return innerCodeRef; }, [type]); const prefix = require_usePrefix.usePrefix(); require_useResizeObserver.useResizeObserver({ ref: getCodeRef(), onResize: () => { if (innerCodeRef?.current && type === "multi") { const { height } = innerCodeRef.current.getBoundingClientRect(); if (maxCollapsedNumberOfRows > 0 && (maxExpandedNumberOfRows <= 0 || maxExpandedNumberOfRows > maxCollapsedNumberOfRows) && height > maxCollapsedNumberOfRows * rowHeightInPixels) setShouldShowMoreLessBtn(true); else setShouldShowMoreLessBtn(false); if (expandedCode && minExpandedNumberOfRows > 0 && height <= minExpandedNumberOfRows * rowHeightInPixels) setExpandedCode(false); } } }); const handleCopyClick = (evt) => { if (copyText || innerCodeRef?.current) (0, copy_to_clipboard.default)(copyText ?? innerCodeRef?.current?.innerText ?? ""); if (onClick) onClick(evt); }; const codeSnippetClasses = (0, classnames.default)(className, `${prefix}--snippet`, { [`${prefix}--snippet--${type}`]: type, [`${prefix}--snippet--disabled`]: type !== "inline" && disabled, [`${prefix}--snippet--expand`]: expandedCode, [`${prefix}--snippet--light`]: light, [`${prefix}--snippet--no-copy`]: hideCopyButton, [`${prefix}--snippet--wraptext`]: wrapText }); const expandCodeBtnText = expandedCode ? showLessText : showMoreText; if (type === "inline") { if (hideCopyButton) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: codeSnippetClasses, children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { id: uid, ref: innerCodeRef, children }) }); return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index$1.default, { ...rest, align, autoAlign, onClick: handleCopyClick, "aria-label": deprecatedAriaLabel || ariaLabel, "aria-describedby": uid, className: codeSnippetClasses, disabled, feedback, feedbackTimeout, children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { id: uid, ref: innerCodeRef, children }) }); } const containerStyle = {}; if (type === "multi") { const styles = {}; if (expandedCode) { if (maxExpandedNumberOfRows > 0) styles.maxHeight = maxExpandedNumberOfRows * rowHeightInPixels; if (minExpandedNumberOfRows > 0) styles.minHeight = minExpandedNumberOfRows * rowHeightInPixels; } else { if (maxCollapsedNumberOfRows > 0) styles.maxHeight = maxCollapsedNumberOfRows * rowHeightInPixels; if (minCollapsedNumberOfRows > 0) styles.minHeight = minCollapsedNumberOfRows * rowHeightInPixels; } if (Object.keys(styles).length) containerStyle.style = styles; } return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { ...rest, className: codeSnippetClasses, children: [ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { ref: codeContainerRef, role: type === "single" || type === "multi" ? "textbox" : void 0, tabIndex: (type === "single" || type === "multi") && !disabled ? 0 : void 0, className: `${prefix}--snippet-container`, "aria-label": deprecatedAriaLabel || ariaLabel || "code-snippet", "aria-readonly": type === "single" || type === "multi" ? true : void 0, "aria-multiline": type === "multi" ? true : void 0, ...containerStyle, children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", { ref: codeContentRef, ...containerStyle, children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { ref: innerCodeRef, children }) }) }), !hideCopyButton && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index$2.default, { align, autoAlign, size: type === "multi" ? "sm" : "md", disabled, onClick: handleCopyClick, feedback, feedbackTimeout, iconDescription: copyButtonDescription }), shouldShowMoreLessBtn && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_index.default, { kind: "ghost", size: "sm", className: `${prefix}--snippet-btn--expand`, disabled, onClick: () => setExpandedCode(!expandedCode), children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: `${prefix}--snippet-btn--text`, children: expandCodeBtnText }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_carbon_icons_react.ChevronDown, { className: `${prefix}--icon-chevron--down ${prefix}--snippet__icon`, name: "chevron--down", role: "img" })] }) ] }); } CodeSnippet.propTypes = { align: require_deprecateValuesWithin.deprecateValuesWithin(prop_types.default.oneOf([ "top", "top-left", "top-right", "bottom", "bottom-left", "bottom-right", "left", "left-bottom", "left-top", "right", "right-bottom", "right-top", "top-start", "top-end", "bottom-start", "bottom-end", "left-end", "left-start", "right-end", "right-start" ]), [ "top", "top-start", "top-end", "bottom", "bottom-start", "bottom-end", "left", "left-start", "left-end", "right", "right-start", "right-end" ], require_mapPopoverAlign.mapPopoverAlign), ["aria-label"]: prop_types.default.string, ariaLabel: require_deprecate.deprecate(prop_types.default.string, "This prop syntax has been deprecated. Please use the new `aria-label`."), autoAlign: prop_types.default.bool, children: prop_types.default.node, className: prop_types.default.string, copyButtonDescription: prop_types.default.string, copyText: prop_types.default.string, disabled: prop_types.default.bool, feedback: prop_types.default.string, feedbackTimeout: prop_types.default.number, hideCopyButton: prop_types.default.bool, light: require_deprecate.deprecate(prop_types.default.bool, "The `light` prop for `CodeSnippet` has been deprecated in favor of the new `Layer` component. It will be removed in the next major release."), maxCollapsedNumberOfRows: prop_types.default.number, maxExpandedNumberOfRows: prop_types.default.number, minCollapsedNumberOfRows: prop_types.default.number, minExpandedNumberOfRows: prop_types.default.number, onClick: prop_types.default.func, showLessText: prop_types.default.string, showMoreText: prop_types.default.string, type: prop_types.default.oneOf([ "single", "inline", "multi" ]), wrapText: prop_types.default.bool }; //#endregion exports.default = CodeSnippet;