@grafana/ui
Version:
Grafana Components Library
103 lines (100 loc) • 3.12 kB
JavaScript
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