UNPKG

@vectara/vectara-ui

Version:

Vectara's design system, codified as a React and Sass component library

85 lines (84 loc) 6.4 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useEffect, useRef, useState } from "react"; import { FocusOn } from "react-focus-on"; import { BiClipboard, BiFullscreen, BiX } from "react-icons/bi"; import classNames from "classnames"; import Prism from "prismjs"; import "prismjs/themes/prism.css"; import "prismjs/components/prism-json"; import "prismjs/components/prism-javascript"; import "prismjs/components/prism-typescript"; import "prismjs/components/prism-bash"; import "prismjs/components/prism-jsx"; import "prismjs/components/prism-tsx"; import "prismjs/components/prism-python"; import { VuiIconButton } from "../button/IconButton"; import { VuiIcon } from "../icon/Icon"; import { VuiFlexContainer } from "../flex/FlexContainer"; import { VuiPortal } from "../portal/Portal"; import { copyToClipboard } from "../../utils/copyToClipboard"; import { VuiScreenBlock } from "../screenBlock/ScreenBlock"; import { VuiFlexItem } from "../flex/FlexItem"; import { getOverlayProps } from "../../utils/getOverlayProps"; import { VuiText } from "../typography/Text"; // PrismJS clears highlighting when language-none is set. export const VuiCode = (_a) => { var { onCopy, isFullscreenEnabled = true, isCopyEnabled = true, language = "none", fullHeight, children = "" } = _a, rest = __rest(_a, ["onCopy", "isFullscreenEnabled", "isCopyEnabled", "language", "fullHeight", "children"]); const [isFullscreen, setIsFullscreen] = useState(false); const codeRef = useRef(null); useEffect(() => { if (codeRef.current) { // Skip highlighting for very large code blocks to avoid performance issues. const contentLength = children.trim().length; if (contentLength > 20000) return; Prism.highlightElement(codeRef.current); } }, [children, language, isFullscreen]); const containerClasses = classNames("vuiCodeContainer", { "vuiCodeContainer--fullHeight": fullHeight }); const classes = classNames("vuiCode", `language-${language}`, { "vuiCode--fullHeight": fullHeight }); const testId = rest["data-testid"]; const actions = (isFullscreenEnabled || isCopyEnabled) && (_jsxs(VuiFlexContainer, Object.assign({ className: "vuiCodeActions", spacing: "xxs" }, { children: [isFullscreenEnabled && (_jsx(VuiIconButton, { color: "neutral", size: "xs", icon: _jsx(VuiIcon, { children: _jsx(BiFullscreen, {}) }), "aria-label": "Full screen", onClick: () => { setIsFullscreen(!isFullscreen); } })), isCopyEnabled && (_jsx(VuiIconButton, { color: "neutral", size: "xs", icon: _jsx(VuiIcon, { children: _jsx(BiClipboard, {}) }), "aria-label": "Copy to clipboard", onClick: () => __awaiter(void 0, void 0, void 0, function* () { yield copyToClipboard(children); if (onCopy) onCopy(); }) }))] }))); const code = (_jsx("pre", Object.assign({ className: "vuiCodePre" }, { children: _jsx("code", Object.assign({ className: classes, ref: codeRef }, { children: children })) }))); return (_jsxs("div", Object.assign({ className: containerClasses }, rest, { children: [code, actions, testId && (_jsx("div", Object.assign({ "data-testid": `${testId}-hidden`, hidden: true }, { children: children }))), _jsx(VuiPortal, { children: isFullscreen && (_jsx(VuiScreenBlock, { children: _jsx(FocusOn, Object.assign({ onEscapeKey: () => { setIsFullscreen(false); } }, { children: _jsxs("div", Object.assign({ className: "vuiCodeFullscreen" }, getOverlayProps("fullscreenCodeTitle"), { children: [_jsxs(VuiFlexContainer, Object.assign({ alignItems: "center", justifyContent: "spaceBetween", className: "vuiCodeFullscreen__actions" }, { children: [_jsx(VuiFlexItem, { children: _jsx(VuiText, { children: _jsx("p", Object.assign({ id: "fullscreenCodeTitle" }, { children: _jsx("strong", { children: "Code" }) })) }) }), _jsx(VuiFlexItem, { children: _jsxs(VuiFlexContainer, Object.assign({ spacing: "xxs" }, { children: [isCopyEnabled && (_jsx(VuiIconButton, { color: "neutral", size: "m", icon: _jsx(VuiIcon, { children: _jsx(BiClipboard, {}) }), "aria-label": "Copy to clipboard", onClick: () => __awaiter(void 0, void 0, void 0, function* () { yield copyToClipboard(children); if (onCopy) onCopy(); }), tooltip: { position: "bottom-end" } })), _jsx(VuiIconButton, { className: "vuiCodeFullscreen__closeButton", color: "neutral", size: "m", icon: _jsx(VuiIcon, { children: _jsx(BiX, {}) }), "aria-label": "Exit fullscreen code", onClick: () => setIsFullscreen(false), tooltip: { position: "bottom-end" } })] })) })] })), code] })) })) })) })] }))); };