UNPKG

@grafana/ui

Version:
103 lines (100 loc) 3.12 kB
import { jsxs, Fragment, jsx } from 'react/jsx-runtime'; import { cx, css } from '@emotion/css'; import { useState, useEffect, useRef, useCallback } from 'react'; import { t } from '@grafana/i18n'; import { useStyles2 } from '../../themes/ThemeContext.mjs'; import { Button } from '../Button/Button.mjs'; import { Icon } from '../Icon/Icon.mjs'; import { InlineToast } from '../InlineToast/InlineToast.mjs'; const SHOW_SUCCESS_DURATION = 2 * 1e3; function ClipboardButton({ onClipboardCopy, onClipboardError, children, getText, icon, variant, ...buttonProps }) { const styles = useStyles2(getStyles); const [showCopySuccess, setShowCopySuccess] = useState(false); useEffect(() => { let timeoutId; if (showCopySuccess) { timeoutId = setTimeout(() => { setShowCopySuccess(false); }, SHOW_SUCCESS_DURATION); } return () => { window.clearTimeout(timeoutId); }; }, [showCopySuccess]); const buttonRef = useRef(null); const copyTextCallback = useCallback(async () => { const textToCopy = getText(); try { await copyText(textToCopy, buttonRef); setShowCopySuccess(true); onClipboardCopy == null ? void 0 : onClipboardCopy(textToCopy); } catch (e) { onClipboardError == null ? void 0 : onClipboardError(textToCopy, e); } }, [getText, onClipboardCopy, onClipboardError]); const copiedText = t("clipboard-button.inline-toast.success", "Copied"); return /* @__PURE__ */ jsxs(Fragment, { children: [ showCopySuccess && /* @__PURE__ */ jsx(InlineToast, { placement: "top", referenceElement: buttonRef.current, children: copiedText }), /* @__PURE__ */ jsxs( Button, { onClick: copyTextCallback, icon, variant: showCopySuccess ? "success" : variant, "aria-label": showCopySuccess ? copiedText : void 0, ...buttonProps, className: cx(styles.button, showCopySuccess && styles.successButton, buttonProps.className), ref: buttonRef, children: [ children, showCopySuccess && /* @__PURE__ */ jsx("div", { className: styles.successOverlay, children: /* @__PURE__ */ jsx(Icon, { name: "check" }) }) ] } ) ] }); } const copyText = async (text, buttonRef) => { var _a; if (navigator.clipboard && window.isSecureContext) { return navigator.clipboard.writeText(text); } else { const textarea = document.createElement("textarea"); (_a = buttonRef.current) == null ? void 0 : _a.appendChild(textarea); textarea.value = text; textarea.focus(); textarea.select(); document.execCommand("copy"); textarea.remove(); } }; const getStyles = (theme) => { return { button: css({ position: "relative" }), successButton: css({ "> *": css({ visibility: "hidden" }) }), successOverlay: css({ position: "absolute", top: 0, bottom: 0, right: 0, left: 0, visibility: "visible" // re-visible the overlay }) }; }; export { ClipboardButton }; //# sourceMappingURL=ClipboardButton.mjs.map