Skip to content

Commit 9de8455

Browse files
Fix: copy button to fallback when navigator.clipboard is not avalible
1 parent ddc7037 commit 9de8455

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

src/features/Overview/SlotPerformance/TransactionBarsCard/ChartTooltip.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { Cross2Icon, CopyIcon, CheckIcon } from "@radix-ui/react-icons";
1414
import { useDebouncedCallback } from "use-debounce";
1515
import RowSeparator from "../../../../components/RowSeparator";
1616
import { getDurationWithUnits } from "./chartUtils";
17+
import { copyToClipboard } from "../../../../utils";
1718

1819
export default function ChartTooltip() {
1920
const slot = useAtomValue(selectedSlotAtom);
@@ -188,7 +189,12 @@ function CuDisplay({ transactions, txnIdx }: CuDisplayProps) {
188189
/>
189190
<IncomeDisplay transactions={transactions} txnIdx={txnIdx} />
190191
<Flex>
191-
<svg height="8" fill="none" className={styles.cuBars}>
192+
<svg
193+
height="8"
194+
fill="none"
195+
className={styles.cuBars}
196+
xmlns="http://www.w3.org/2000/svg"
197+
>
192198
<rect
193199
height="8"
194200
width={`${consumedPct}%`}
@@ -312,7 +318,11 @@ function StateDurationDisplay({
312318
<>
313319
<RowSeparator />
314320
<Flex>
315-
<svg height="36" className={styles.durationContainer}>
321+
<svg
322+
height="36"
323+
className={styles.durationContainer}
324+
xmlns="http://www.w3.org/2000/svg"
325+
>
316326
<rect
317327
height="8"
318328
width={`${durationRatios.preLoading}%`}
@@ -448,12 +458,12 @@ function LabelValueDisplay({
448458
>
449459
<Flex gap="2" align="center">
450460
<Text>{label}</Text>
451-
{copyValue && navigator.clipboard && (
461+
{copyValue && (
452462
<Button
453463
variant="ghost"
454464
size="1"
455465
onClick={(e) => {
456-
void navigator.clipboard.writeText(copyValue);
466+
copyToClipboard(copyValue);
457467
setHasCopied(true);
458468
resetHasCopied();
459469
// Seems to be caught sometimes by the outside tooltip click handler?

src/utils.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,32 @@ export const hasModKey = ({
111111
metaKey,
112112
}: KeyboardEvent | React.MouseEvent | WheelEvent) =>
113113
shiftKey || ctrlKey || metaKey;
114+
115+
export function copyToClipboard(copyValue: string) {
116+
if (navigator.clipboard) {
117+
void navigator.clipboard.writeText(copyValue);
118+
return;
119+
}
120+
121+
// Copy fallback for when not https or localhost
122+
const copyEl = document.createElement("textarea");
123+
copyEl.value = copyValue;
124+
125+
// Move el out of the viewport so it's not visible
126+
copyEl.style.position = "absolute";
127+
copyEl.style.left = "-999999px";
128+
129+
document.body.appendChild(copyEl);
130+
copyEl.select();
131+
132+
try {
133+
const successful = document.execCommand("copy");
134+
if (!successful) {
135+
console.error("Failed to copy text", copyValue);
136+
}
137+
} catch (error) {
138+
console.error("Failed to copy text", copyValue, error);
139+
} finally {
140+
document.body.removeChild(copyEl);
141+
}
142+
}

0 commit comments

Comments
 (0)