fix: add clipboard fallback for copy actions#66
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a shared clipboard helper to address Windows 11/Edge copy failures by providing a legacy document.execCommand("copy") fallback when the Clipboard API is unavailable or denied, and wires it into existing copy UI points.
Changes:
- Introduce
lib/clipboard.tswithcopyToClipboard()(Clipboard API primary + legacy fallback). - Replace direct
navigator.clipboard.writeTextcalls in object version ID copy, object path copy button, andCopyInputwith the shared helper.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| lib/clipboard.ts | New shared clipboard helper with fallback copy implementation. |
| components/object/versions.tsx | Uses copyToClipboard() for version ID copy. |
| components/object/path-links.tsx | Uses copyToClipboard() in the path copy hook. |
| components/copy-input.tsx | Uses copyToClipboard() for input copy action. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| document.body.appendChild(textarea) | ||
| textarea.focus() | ||
| textarea.select() | ||
|
|
||
| let copied = false | ||
| try { | ||
| copied = document.execCommand("copy") | ||
| } catch { | ||
| copied = false | ||
| } finally { | ||
| document.body.removeChild(textarea) | ||
| } |
There was a problem hiding this comment.
legacyCopyToClipboard assumes document.body exists and will throw if it’s null (e.g., called very early or in unusual document states). Consider guarding for document.body before appendChild/removeChild and returning false if it’s not available.
| textarea.focus() | ||
| textarea.select() | ||
|
|
||
| let copied = false | ||
| try { | ||
| copied = document.execCommand("copy") | ||
| } catch { | ||
| copied = false | ||
| } finally { | ||
| document.body.removeChild(textarea) | ||
| } |
There was a problem hiding this comment.
The legacy fallback moves focus to a hidden <textarea> (textarea.focus()), which can disrupt keyboard users and screen readers, and focus is not restored afterward. Save the previously focused element and restore focus after copying/removal (or otherwise ensure focus remains on the triggering control).
| await navigator.clipboard.writeText(value) | ||
| return | ||
| } catch (error) { | ||
| // Fallback to legacy copy only when Clipboard API is denied or unsupported in current context |
There was a problem hiding this comment.
The comment says the legacy path is used "only when Clipboard API is denied or unsupported", but the code falls back on any navigator.clipboard.writeText error. Either narrow the fallback condition (e.g., specific error names) or adjust the comment to match actual behavior.
| // Fallback to legacy copy only when Clipboard API is denied or unsupported in current context | |
| // Fallback to legacy copy on any Clipboard API error (e.g., denied or unsupported in current context) |
Fix Windows clipboard copy failures in object pages by adding a shared clipboard helper with fallback path.
This addresses issue #63: Windows 11 copy link failure.