mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
UI/ClipboardButton: Remove ClipboardJS in favor of native Clipboard API (#42996)
* UI/ClipboardButton: Remove ClipboardJS in favor of native Clipboard API Closes #42365 * Add backwards compatibility
This commit is contained in:
@@ -48,7 +48,6 @@
|
||||
"ansicolor": "1.1.95",
|
||||
"calculate-size": "1.1.1",
|
||||
"classnames": "2.3.1",
|
||||
"clipboard": "2.0.4",
|
||||
"core-js": "3.20.0",
|
||||
"d3": "5.15.0",
|
||||
"date-fns": "2.28.0",
|
||||
@@ -119,7 +118,6 @@
|
||||
"@testing-library/react-hooks": "7.0.2",
|
||||
"@testing-library/user-event": "13.5.0",
|
||||
"@types/classnames": "2.3.0",
|
||||
"@types/clipboard": "2.0.1",
|
||||
"@types/common-tags": "^1.8.0",
|
||||
"@types/d3": "7.1.0",
|
||||
"@types/enzyme": "3.10.5",
|
||||
|
||||
@@ -1,51 +1,44 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import Clipboard from 'clipboard';
|
||||
import React, { useCallback, useRef } from 'react';
|
||||
import { Button, ButtonProps } from '../Button';
|
||||
|
||||
/** @deprecated Will be removed in next major release */
|
||||
interface ClipboardEvent {
|
||||
action: string;
|
||||
text: string;
|
||||
trigger: Element;
|
||||
clearSelection(): void;
|
||||
}
|
||||
|
||||
export interface Props extends ButtonProps {
|
||||
/** A function that returns text to be copied */
|
||||
getText(): string;
|
||||
/** Callback when the text has been successfully copied */
|
||||
onClipboardCopy?(e: Clipboard.Event): void;
|
||||
onClipboardCopy?(e: ClipboardEvent): void;
|
||||
/** Callback when there was an error copying the text */
|
||||
onClipboardError?(e: Clipboard.Event): void;
|
||||
onClipboardError?(e: ClipboardEvent): void;
|
||||
}
|
||||
|
||||
export class ClipboardButton extends PureComponent<Props> {
|
||||
private clipboard!: Clipboard;
|
||||
private elem!: HTMLButtonElement;
|
||||
const dummyClearFunc = () => {};
|
||||
|
||||
setRef = (elem: HTMLButtonElement) => {
|
||||
this.elem = elem;
|
||||
};
|
||||
export function ClipboardButton({ onClipboardCopy, onClipboardError, children, getText, ...buttonProps }: Props) {
|
||||
// Can be removed in 9.x
|
||||
const buttonRef = useRef<null | HTMLButtonElement>(null);
|
||||
const copyText = useCallback(() => {
|
||||
const copiedText = getText();
|
||||
const dummyEvent: ClipboardEvent = {
|
||||
action: 'copy',
|
||||
clearSelection: dummyClearFunc,
|
||||
text: copiedText,
|
||||
trigger: buttonRef.current!,
|
||||
};
|
||||
navigator.clipboard
|
||||
.writeText(copiedText)
|
||||
.then(() => (onClipboardCopy?.(dummyEvent), () => onClipboardError?.(dummyEvent)));
|
||||
}, [getText, onClipboardCopy, onClipboardError]);
|
||||
|
||||
componentDidMount() {
|
||||
const { getText, onClipboardCopy, onClipboardError } = this.props;
|
||||
|
||||
this.clipboard = new Clipboard(this.elem, {
|
||||
text: () => getText(),
|
||||
});
|
||||
|
||||
this.clipboard.on('success', (e: Clipboard.Event) => {
|
||||
onClipboardCopy && onClipboardCopy(e);
|
||||
});
|
||||
|
||||
this.clipboard.on('error', (e: Clipboard.Event) => {
|
||||
onClipboardError && onClipboardError(e);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.clipboard.destroy();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { getText, onClipboardCopy, onClipboardError, children, ...buttonProps } = this.props;
|
||||
|
||||
return (
|
||||
<Button {...buttonProps} ref={this.setRef}>
|
||||
{children}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Button onClick={copyText} {...buttonProps} ref={buttonRef}>
|
||||
{children}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user