Skip to content

Commit

Permalink
Migrate CopyButton from deprecated to modern clipboard
Browse files Browse the repository at this point in the history
  • Loading branch information
cskrov committed May 25, 2023
1 parent aa3b4c2 commit e11094a
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 75 deletions.
9 changes: 9 additions & 0 deletions .changeset/purple-dryers-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@navikt/ds-react": patch
---

Migrert `CopyButton` til `Clipboard API`

- `CopyButton` bruker nå [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API).
- `execCommand()` er fjernet fordi den [er deprecated](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand).
- Nettlesere som ikke støtter `Clipboard API` vil falle tilbake på `window.prompt()`.
83 changes: 8 additions & 75 deletions @navikt/core/react/src/util/copy.ts
Original file line number Diff line number Diff line change
@@ -1,81 +1,14 @@
// https://github.com/sudodoki/copy-to-clipboard/blob/main/index.js

const defaultMessage = "Kopier til utklippstavle: #{key}, Enter";

function format(message) {
const copyKey = (/mac os x/i.test(navigator.userAgent) ? "⌘" : "Ctrl") + "+C";
return message.replace(/#{\s*key\s*}/g, copyKey);
}

export default function copy(text) {
let debug,
message,
range,
selection,
mark,
success = false;
debug = process.env.NODE_ENV !== "production";
export default async function copy(text: string): Promise<void> {
try {
range = document.createRange();
selection = document.getSelection();

mark = document.createElement("span");
mark.textContent = text;
// avoid screen readers from reading out loud the text
mark.ariaHidden = "true";
// reset user styles for span element
mark.style.all = "unset";
// prevents scrolling to the end of the page
mark.style.position = "fixed";
mark.style.top = 0;
mark.style.clip = "rect(0, 0, 0, 0)";
// used to preserve spaces and line breaks
mark.style.whiteSpace = "pre";
// do not inherit user-select (it may be `none`)
mark.style.webkitUserSelect = "text";
mark.style.MozUserSelect = "text";
mark.style.msUserSelect = "text";
mark.style.userSelect = "text";
mark.addEventListener("copy", function (e) {
e.stopPropagation();
});

document.body.appendChild(mark);

range.selectNodeContents(mark);
selection.addRange(range);

const successful = document.execCommand("copy");
if (!successful) {
throw new Error("copy command was unsuccessful");
}
success = true;
await navigator.clipboard.writeText(text);
} catch (err) {
debug && console.error("unable to copy using execCommand: ", err);
debug && console.warn("trying IE specific stuff");
try {
(window as any).clipboardData.setData("text", text);

success = true;
} catch (err) {
debug && console.error("unable to copy using clipboardData: ", err);
debug && console.error("falling back to prompt");
message = format(defaultMessage);
window.prompt(message, text);
}
} finally {
if (selection) {
if (typeof selection.removeRange == "function") {
selection.removeRange(range);
} else {
selection.removeAllRanges();
}
if (process.env.NODE_ENV !== "production") {
console.error("Unable to copy using Clipboard API", err);
}

if (mark) {
document.body.removeChild(mark);
}
// Fallback for browsers that do not support the Clipboard API.
const copyKey = /mac os x/i.test(navigator.userAgent) ? "⌘" : "Ctrl";
const message = `Kopier til utklippstavle: ${copyKey}+C, Enter`;
window.prompt(message, text);
}

return success;
}

0 comments on commit e11094a

Please sign in to comment.