UNPKG

react-code-view

Version:
100 lines (95 loc) 4.66 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var _react = _interopRequireWildcard(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _copyToClipboard = _interopRequireDefault(require("copy-to-clipboard")); var _mergeRefs = _interopRequireDefault(require("./utils/mergeRefs")); var _Copy = require("./icons/Copy"); var _Check = require("./icons/Check"); var _jsxRuntime = require("react/jsx-runtime"); var _excluded = ["className"], _excluded2 = ["children", "className", "copyButtonProps"]; function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } /** * Creates and appends a copy button to a code container * @param container - The container element to append the copy button to * @param buttonProps - Additional props to apply to the copy button */ function createCopyButton(container, buttonProps) { // If the container is null or the container already has a copy button, return if (!container || container.querySelector('button[data-type="copy"]')) { return; } var _ref = buttonProps || {}, className = _ref.className, rest = (0, _objectWithoutPropertiesLoose2["default"])(_ref, _excluded); var button = document.createElement('button'); button.dataset['type'] = 'copy'; button.title = 'Copy code'; button.setAttribute('aria-label', 'Copy code'); button.innerHTML = (0, _Copy.svgTpl)(_Copy.iconPath); if (className) { button.className = className; } button.onclick = function (e) { var _container$querySelec; e.preventDefault(); var code = (_container$querySelec = container.querySelector('code')) === null || _container$querySelec === void 0 ? void 0 : _container$querySelec.textContent; var icon = button.querySelector('.copy-icon-path'); // Show check icon to indicate successful copy icon === null || icon === void 0 ? void 0 : icon.setAttribute('d', _Check.iconPath); if (code) { (0, _copyToClipboard["default"])(code); } // Reset to copy icon after 2 seconds setTimeout(function () { icon === null || icon === void 0 ? void 0 : icon.setAttribute('d', _Copy.iconPath); }, 2000); }; // Apply additional button properties if (rest) { Object.entries(rest).forEach(function (_ref2) { var key = _ref2[0], value = _ref2[1]; if (value !== undefined) { button.setAttribute(key, String(value)); } }); } container.appendChild(button); } /** * Renders markdown content with code blocks that have copy buttons */ var MarkdownRenderer = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) { var children = props.children, className = props.className, copyButtonProps = props.copyButtonProps, rest = (0, _objectWithoutPropertiesLoose2["default"])(props, _excluded2); var mdRef = (0, _react.useRef)(null); (0, _react.useEffect)(function () { var _mdRef$current; // Add copy buttons to all code blocks var codeBlocks = (_mdRef$current = mdRef.current) === null || _mdRef$current === void 0 ? void 0 : _mdRef$current.querySelectorAll('.rcv-code-renderer'); codeBlocks === null || codeBlocks === void 0 ? void 0 : codeBlocks.forEach(function (codeBlock) { createCopyButton(codeBlock, copyButtonProps); }); // We only want to run this once when the component mounts // eslint-disable-next-line react-hooks/exhaustive-deps }, []); if (!children) { return null; } return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", (0, _extends2["default"])({}, rest, { ref: (0, _mergeRefs["default"])(mdRef, ref), className: (0, _classnames["default"])(className, 'rcv-markdown'), dangerouslySetInnerHTML: { __html: children } })); }); var _default = exports["default"] = MarkdownRenderer;