142 lines
3.7 KiB
JavaScript
142 lines
3.7 KiB
JavaScript
import {
|
|
LitElement,
|
|
html,
|
|
css
|
|
} from "https://unpkg.com/lit@2.1.4/index.js?module";
|
|
|
|
class CopyTable extends LitElement {
|
|
static styles = css`
|
|
:host {
|
|
display: grid;
|
|
grid-template-columns: minmax(auto, max-content) max-content;
|
|
gap: 0.5rem;
|
|
width: 100%;
|
|
overflow: hidden;
|
|
}
|
|
.actions {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: start;
|
|
align-items: start;
|
|
gap: 0.5rem;
|
|
}
|
|
button {
|
|
appearance: none;
|
|
border: none;
|
|
background: transparent;
|
|
padding: 0;
|
|
}
|
|
a {
|
|
color: currentColor;
|
|
}
|
|
.overflow {
|
|
max-width: 100%;
|
|
overflow-x: auto;
|
|
}
|
|
`;
|
|
|
|
static properties = {
|
|
_success: { state: false }
|
|
};
|
|
|
|
constructor() {
|
|
super();
|
|
const trs = this.querySelectorAll("tr");
|
|
|
|
this.CSV = (function () {
|
|
let returnString = [];
|
|
trs.forEach((tr) => {
|
|
let tds = tr.querySelectorAll("td,th");
|
|
let tdContent = [...tds].map((td) =>
|
|
td.textContent.match(",") ? `"${td.textContent}"` : td.textContent
|
|
);
|
|
returnString.push(tdContent.join(","));
|
|
});
|
|
return returnString.join("\n");
|
|
})();
|
|
}
|
|
|
|
copyToClipboard(event) {
|
|
var type = "text/plain";
|
|
var blob = new Blob([this.CSV], { type });
|
|
var data = [new ClipboardItem({ [type]: blob })];
|
|
|
|
navigator.clipboard.write(data).then(() => {
|
|
this._success = true;
|
|
setTimeout(() => {
|
|
this._success = false;
|
|
}, 1000);
|
|
});
|
|
}
|
|
|
|
render() {
|
|
return html`
|
|
<div class="overflow">
|
|
<slot></slot>
|
|
</div>
|
|
|
|
<div class="actions">
|
|
<button aria-label="Copy as CSV" @click="${this.copyToClipboard}">
|
|
${this._success
|
|
? html`
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
height="24"
|
|
width="24"
|
|
>
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"
|
|
/>
|
|
</svg>
|
|
`
|
|
: html`
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
height="24"
|
|
width="24"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"
|
|
/>
|
|
</svg>
|
|
`}
|
|
</button>
|
|
<a
|
|
aria-label="Download CSV"
|
|
download="table.csv"
|
|
href="data:,${encodeURIComponent(this.CSV)}"
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
height="24"
|
|
width="24"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
|
/>
|
|
</svg>
|
|
</a>
|
|
</div>
|
|
`;
|
|
}
|
|
}
|
|
|
|
customElements.define("copy-table", CopyTable); |