diff --git a/.changeset/purple-dryers-buy.md b/.changeset/purple-dryers-buy.md new file mode 100644 index 00000000000..3b9059601b0 --- /dev/null +++ b/.changeset/purple-dryers-buy.md @@ -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()`. diff --git a/@navikt/core/react/src/util/copy.ts b/@navikt/core/react/src/util/copy.ts index 54adbda5dd5..756f1f9a4ad 100644 --- a/@navikt/core/react/src/util/copy.ts +++ b/@navikt/core/react/src/util/copy.ts @@ -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 { 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; }