diff --git a/resources/js/copy-button.js b/resources/js/copy-button.js index 0ce8d5d67d..b62eaa120e 100644 --- a/resources/js/copy-button.js +++ b/resources/js/copy-button.js @@ -12,15 +12,22 @@ export function initializeCopyButtonComponent() { await navigator.clipboard.writeText(value); } else { // Deprecated, but the only copy path on plain http (non-secure contexts). + // The textarea goes next to the button, not into
: a modal's x-trap + // pulls focus back from nodes outside it, which clears the selection. + const previousFocus = document.activeElement; const textarea = document.createElement('textarea'); textarea.value = value; textarea.setAttribute('readonly', ''); + textarea.setAttribute('tabindex', '-1'); textarea.style.position = 'fixed'; textarea.style.left = '-9999px'; - document.body.appendChild(textarea); + this.$el.after(textarea); + textarea.focus({ preventScroll: true }); textarea.select(); + textarea.setSelectionRange(0, textarea.value.length); const ok = document.execCommand('copy'); - document.body.removeChild(textarea); + textarea.remove(); + previousFocus?.focus?.({ preventScroll: true }); if (!ok) { throw new Error('Copy command was rejected.'); } diff --git a/resources/views/livewire/project/shared/cloudflare-autoconfigure.blade.php b/resources/views/livewire/project/shared/cloudflare-autoconfigure.blade.php index 8d102ff47f..9b565c4e98 100644 --- a/resources/views/livewire/project/shared/cloudflare-autoconfigure.blade.php +++ b/resources/views/livewire/project/shared/cloudflare-autoconfigure.blade.php @@ -223,39 +223,15 @@ @if (filled($dnsCopyText)) -{{ count($dnsHints) }} {{ count($dnsHints) === 1 ? 'entry' : 'entries' }} ยท BIND zone format