119 lines
3.4 KiB
JavaScript
119 lines
3.4 KiB
JavaScript
const smCopy = document.createElement('template')
|
|
smCopy.innerHTML = `
|
|
<style>
|
|
*{
|
|
padding: 0;
|
|
margin: 0;
|
|
-webkit-box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
}
|
|
:host{
|
|
display: -webkit-inline-box;
|
|
display: -ms-inline-flexbox;
|
|
display: inline-flex;
|
|
--accent-color: #4d2588;
|
|
--text-color: 17, 17, 17;
|
|
--background-color: 255, 255, 255;
|
|
--padding: 0;
|
|
--background-color: inherit;
|
|
--button-background-color: rgba(var(--text-color), 0.2);
|
|
--button-border-radius: 0.3rem;
|
|
}
|
|
.copy{
|
|
display: grid;
|
|
gap: 0.5rem;
|
|
padding: var(--padding);
|
|
align-items: center;
|
|
grid-template-columns: minmax(0, 1fr) auto;
|
|
}
|
|
.copy-content{
|
|
overflow-wrap: break-word;
|
|
word-wrap: break-word;
|
|
}
|
|
.copy-button{
|
|
display: inline-flex;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
border: none;
|
|
padding: 0.4rem;
|
|
background-color: inherit;
|
|
border-radius: var(--button-border-radius);
|
|
}
|
|
.copy-button:active{
|
|
background-color: var(--button-background-color);
|
|
}
|
|
.icon{
|
|
height: 1.2rem;
|
|
width: 1.2rem;
|
|
fill: rgba(var(--text-color), 0.8);
|
|
}
|
|
@media (any-hover: hover){
|
|
.copy:hover .copy-button{
|
|
opacity: 1;
|
|
}
|
|
.copy-button{
|
|
opacity: 0.6;
|
|
}
|
|
.copy-button:hover{
|
|
background-color: var(--button-background-color);
|
|
}
|
|
}
|
|
</style>
|
|
</style>
|
|
<section class="copy">
|
|
<p class="copy-content"></p>
|
|
<button part="button" class="copy-button" title="copy">
|
|
<slot name="copy-icon">
|
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M7 6V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1.001 1.001 0 0 1 3 21l.003-14c0-.552.45-1 1.007-1H7zM5.003 8L5 20h10V8H5.003zM9 6h8v10h2V4H9v2z"/></svg>
|
|
</slot>
|
|
</button>
|
|
</section>
|
|
`;
|
|
customElements.define('sm-copy',
|
|
class extends HTMLElement {
|
|
constructor() {
|
|
super()
|
|
this.attachShadow({
|
|
mode: 'open'
|
|
}).append(smCopy.content.cloneNode(true))
|
|
|
|
this.copyContent = this.shadowRoot.querySelector('.copy-content')
|
|
this.copyButton = this.shadowRoot.querySelector('.copy-button')
|
|
|
|
this.copy = this.copy.bind(this)
|
|
}
|
|
static get observedAttributes() {
|
|
return ['value']
|
|
}
|
|
set value(val) {
|
|
this.setAttribute('value', val)
|
|
}
|
|
get value() {
|
|
return this.getAttribute('value')
|
|
}
|
|
fireEvent() {
|
|
this.dispatchEvent(
|
|
new CustomEvent('copy', {
|
|
composed: true,
|
|
bubbles: true,
|
|
cancelable: true,
|
|
})
|
|
)
|
|
}
|
|
copy() {
|
|
navigator.clipboard.writeText(this.copyContent.textContent)
|
|
.then(res => this.fireEvent())
|
|
.catch(err => console.error(err))
|
|
}
|
|
connectedCallback() {
|
|
this.copyButton.addEventListener('click', this.copy)
|
|
}
|
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
if (name === 'value') {
|
|
this.copyContent.textContent = newValue
|
|
}
|
|
}
|
|
disconnectedCallback() {
|
|
this.copyButton.removeEventListener('click', this.copy)
|
|
}
|
|
}) |