Created
July 13, 2024 12:01
-
-
Save CamKem/042ca4cbac70bf3c7f6ecada5a792b33 to your computer and use it in GitHub Desktop.
playing around
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const copyCode = () => ({ | |
codeElements: [], | |
init() { | |
this.codeElements = this.$el.querySelectorAll('code'); | |
this.addCopyButtons(); | |
this.mutate(); | |
}, | |
mutate() { | |
// mutation observer to reinit buttons when new code elements are added | |
const observer = new MutationObserver((mutations) => { | |
mutations.forEach((mutation) => { | |
// if this.el is the target, reinit buttons | |
if (mutation.target === this.$el) { | |
this.reinitButtons(); | |
} | |
}); | |
}) | |
observer.observe(this.$el, { childList: true, subtree: true }); | |
}, | |
copyToClipboard(item) { | |
this.$clipboard(item) | |
this.$notify('Copied to clipboard.', { | |
wrapperId: 'flashMessageWrapper', | |
templateId: 'flashMessageTemplate', | |
autoClose: 3000, | |
autoRemove: 4000 | |
}) | |
}, | |
reinitButtons() { | |
this.codeElements = this.$el.querySelectorAll('code'); | |
this.addCopyButtons(); | |
}, | |
addCopyButtons() { | |
const copyIconOutline = new DOMParser().parseFromString( | |
`<svg xmlns="http://www.w3.org/2000/svg" class="size-5" viewBox="0 0 24 24" fill="currentColor" fill-opacity="50%"><path d="M20 2H10c-1.103 0-2 .897-2 2v4H4c-1.103 0-2 .897-2 2v10c0 1.103.897 2 2 2h10c1.103 0 2-.897 2-2v-4h4c1.103 0 2-.897 2-2V4c0-1.103-.897-2-2-2zM4 20V10h10l.002 10H4zm16-6h-4v-4c0-1.103-.897-2-2-2h-4V4h10v10z"></path><path d="M6 12h6v2H6zm0 4h6v2H6z"></path></svg>` | |
, 'image/svg+xml').documentElement; | |
const copyIconSolid = new DOMParser().parseFromString( | |
`<svg xmlns="http://www.w3.org/2000/svg" class="size-5" viewBox="0 0 24 24" fill="currentColor" fill-opacity="50%"><path d="M20 2H10a2 2 0 0 0-2 2v2h8a2 2 0 0 1 2 2v8h2a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2z"></path><path d="M4 22h10c1.103 0 2-.897 2-2V10c0-1.103-.897-2-2-2H4c-1.103 0-2 .897-2 2v10c0 1.103.897 2 2 2zm2-10h6v2H6v-2zm0 4h6v2H6v-2z"></path></svg>` | |
, 'image/svg+xml').documentElement; | |
const toggleIcon = (button) => { | |
if (button.contains(copyIconOutline)) { | |
button.removeChild(copyIconOutline); | |
button.appendChild(copyIconSolid); | |
} else if (button.contains(copyIconSolid)) { | |
button.removeChild(copyIconSolid); | |
button.appendChild(copyIconOutline); | |
} else { | |
button.appendChild(copyIconOutline); | |
} | |
} | |
const positionButton = (button, el) => { | |
const rect = el.getBoundingClientRect(); | |
const m = 8; | |
button.style.position = 'sticky'; | |
button.style.left = `${rect.width - button.offsetWidth - (m * 2)}px`; | |
button.style.top = `-${m * 5}px`; | |
button.style.bottom = `100%`; | |
button.style.margin = `-${m}px`; | |
} | |
this.codeElements.forEach((codeElement) => { | |
codeElement.classList.add('group/code'); | |
const button = document.createElement('button'); | |
const setupButton = () => { | |
// to make it appear on hover | |
button.classList.add( | |
'opacity-0', | |
'group-hover/code:opacity-100', | |
'text-xs', | |
'text-pink-400', | |
'cursor-pointer', | |
'focus:outline-none', | |
'transition-colors', | |
'hover:text-white', | |
'z-10', | |
'p-1', | |
'rounded-md', | |
'bg-pink-900', | |
'bg-opacity-50', | |
'transition-opacity', | |
'duration-200', | |
); | |
button.title = 'Copy'; | |
button.setAttribute( | |
'data-navigate-ignore', | |
'true' | |
); | |
toggleIcon(button); | |
positionButton(button, codeElement); | |
} | |
this.$nextTick(() => { | |
setupButton(); | |
}); | |
window.addEventListener( | |
'resize', | |
positionButton.bind(null, button, codeElement) | |
); | |
button.addEventListener('click', () => { | |
this.copyToClipboard(codeElement.innerText); | |
toggleIcon(button); | |
positionButton(button, codeElement); | |
setTimeout(() => { | |
toggleIcon(button); | |
positionButton(button, codeElement); | |
}, 1000); | |
}); | |
codeElement.appendChild(button); | |
}); | |
} | |
}); | |
export {copyCode} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment