clipboard copy falls back correctly inside dialogs
This commit is contained in:
1 file changed
+15
-3
@@ -12,20 +12,32 @@ export async function copyToClipboard(text: string): Promise<boolean> {
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: hidden textarea + execCommand for HTTP contexts
|
||||
// Fallback: hidden textarea + execCommand for HTTP (insecure) contexts, where
|
||||
// navigator.clipboard is unavailable. The textarea must live INSIDE the current
|
||||
// focus-trap (e.g. a shadcn/bits-ui Dialog): appended to document.body it sits
|
||||
// outside the trap, which yanks focus back to the dialog before execCommand runs,
|
||||
// so the copy silently fails and pastes stale clipboard content (#1488). Mount it
|
||||
// in the open dialog when there is one, else document.body.
|
||||
try {
|
||||
const openDialog = document.querySelector<HTMLElement>('[role="dialog"]');
|
||||
const host = openDialog ?? document.body;
|
||||
const active = document.activeElement as HTMLElement | null;
|
||||
|
||||
const textarea = document.createElement('textarea');
|
||||
textarea.value = text;
|
||||
textarea.setAttribute('readonly', '');
|
||||
textarea.style.position = 'fixed';
|
||||
textarea.style.left = '-9999px';
|
||||
textarea.style.top = '-9999px';
|
||||
textarea.style.opacity = '0';
|
||||
document.body.appendChild(textarea);
|
||||
host.appendChild(textarea);
|
||||
textarea.focus();
|
||||
textarea.select();
|
||||
textarea.setSelectionRange(0, textarea.value.length);
|
||||
const ok = document.execCommand('copy');
|
||||
document.body.removeChild(textarea);
|
||||
host.removeChild(textarea);
|
||||
// Restore focus to whatever the user had (keeps the dialog's focus-trap happy).
|
||||
active?.focus?.();
|
||||
if (ok) return true;
|
||||
} catch {
|
||||
/* fall through */
|
||||
|
||||
Reference in new issue
Block a user