UNPKG

@phx-hook/copy-to-clipboard

Version:
74 lines (59 loc) 2.06 kB
export default function (options = {}) { const copyEvent = options.copyEvent || "phx:copy"; return { mounted() { this.handleCopy = this.handleCopy.bind(this); this.el.addEventListener(copyEvent, this.handleCopy); }, handleCopy(event) { event.stopPropagation(); let format = this.el.dataset["copyFormat"] || "plain"; if (!(format === "plain" || format === "html")) { throw new Error( `data-copy-format must be "plain" or "html", received: "${format}"`, ); } let dataPlain; let dataHTML; if (this.el.dataset["copyValue"] !== undefined) { dataPlain = dataHTML = this.el.dataset["copyValue"]; } else { let copyEl; let copyContents = this.el.dataset["copyContents"]; if (copyContents === "") { copyEl = this.el; } else if (copyContents !== undefined) { copyEl = this.el.querySelector(copyContents); } if (copyEl) { dataPlain = copyEl.innerText; dataHTML = copyEl.innerHTML; } } // If available, use the dispatcher element to communicate copy state let copierEl = event.detail.dispatcher || this.el; let copySuccess = () => { copierEl.dataset["copied"] = "copied"; let resetAfter = parseInt(this.el.dataset["copyResetAfter"]); if (!isNaN(resetAfter)) { setTimeout(() => { delete copierEl.dataset["copied"]; }, resetAfter); } }; if (format === "plain" && dataPlain) { navigator.clipboard.writeText(dataPlain).then(() => { copySuccess(); }); } else if (format === "html" && dataPlain && dataHTML) { let clipboardItem = new ClipboardItem({ "text/plain": new Blob([dataPlain], { type: "text/plain" }), "text/html": new Blob([dataHTML], { type: "text/html" }), }); navigator.clipboard.write([clipboardItem]).then(() => { copySuccess(); }); } }, }; }