diff --git a/assets/images/icon-copy.svg b/assets/images/icon-copy.svg
new file mode 100644
index 000000000..bdee8facd
--- /dev/null
+++ b/assets/images/icon-copy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/javascripts/new-javascripts/application.js b/assets/javascripts/new-javascripts/application.js
index 4b966bfae..955afc964 100644
--- a/assets/javascripts/new-javascripts/application.js
+++ b/assets/javascripts/new-javascripts/application.js
@@ -45,28 +45,41 @@ document.addEventListener('DOMContentLoaded', function () {
if (navigator && navigator.clipboard) {
const codeBlocks = document.querySelectorAll(
':is([class^="language-"] pre.highlight, .code-box pre code)',
- )
+ );
+
+ const copyIcon = ``;
+ const copiedIcon = ``;
codeBlocks.forEach((codeBlock) => {
- const button = document.createElement('button')
- const codeElement = codeBlock.querySelector('code') || codeBlock
- const container = codeBlock.parentElement
+ const button = document.createElement('button');
+ const codeElement = codeBlock.querySelector('code') || codeBlock;
+ const container = codeBlock.parentElement;
- container.style.position = 'relative'
- container.appendChild(button)
- button.innerText = 'copy'
+ button.classList.add('copy-button');
+ container.appendChild(button);
+ button.innerHTML = copyIcon
button.addEventListener('mousedown', async () => {
- const originalText = button.innerText
+ const originalIcon = copyIcon; // Store the original icon
- await navigator.clipboard.writeText(codeElement.innerText)
- button.innerText = 'copied!'
+ try {
+ await navigator.clipboard.writeText(codeElement.innerText);
- setTimeout(() => {
- button.innerText = originalText
- }, 1000)
- })
- })
+ button.classList.add('copied');
+ button.innerHTML = copiedIcon;
+
+ setTimeout(() => {
+ button.classList.remove('copied');
+ button.innerHTML = originalIcon;
+ }, 1000);
+ } catch (err) {
+ console.error('Failed to copy text: ', err);
+ setTimeout(() => {
+ button.innerHTML = originalIcon; // Revert to original icon
+ }, 1000);
+ }
+ });
+ });
}
// Check for reduced motion setting
diff --git a/assets/stylesheets/new-stylesheets/_syntax.scss b/assets/stylesheets/new-stylesheets/_syntax.scss
index bce4d85a8..50d0da39f 100644
--- a/assets/stylesheets/new-stylesheets/_syntax.scss
+++ b/assets/stylesheets/new-stylesheets/_syntax.scss
@@ -3,27 +3,43 @@
position: relative;
button {
- background-color: #c5c5c5;
- color: white;
- border: 0;
- padding: 5px 8px;
- font-family: sans-serif;
- transition: background-color 0.2s;
- cursor: pointer;
position: absolute;
- top: 0;
- right: 0;
+ top: 1em;
+ right: 1em;
+ background: none;
+ border: medium;
+ cursor: pointer;
+ padding: 7px 6px;
+ border-radius: 6px;
+ transition: all 0.2s ease-in-out;
display: none;
- border-radius: 0 10px 0 0;
+ background-color: var(--color-syntax-clipboard-bg);
+
+ svg {
+ width: 20px;
+ height: 20px;
+ opacity: 0.8;
+ }
+
+ &.copied {
+ svg {
+ color: var(--color-syntax-clipboard-check-color);
+ }
+ }
+
&:hover {
- background-color: #868686;
+ background-color: var(--color-syntax-clipboard-hover-bg);
+
+ svg {
+ opacity: 1;
+ }
}
}
&:hover {
button {
- display: block;
+ display: flex;
}
}
}
diff --git a/assets/stylesheets/new-stylesheets/_themes.scss b/assets/stylesheets/new-stylesheets/_themes.scss
index fa9171512..55392a861 100644
--- a/assets/stylesheets/new-stylesheets/_themes.scss
+++ b/assets/stylesheets/new-stylesheets/_themes.scss
@@ -70,6 +70,10 @@
--nav-scroller-gradient-end: #fff;
// syntax
+ --color-syntax-clipboard-bg: rgb(223, 223, 247);
+ --color-syntax-clipboard-hover-bg: rgb(216, 216, 242);
+ --color-syntax-clipboard-check-color: rgb(12, 156, 12);
+
--color-syntax-attributes: rgb(148, 113, 0);
--color-syntax-characters: rgb(39, 42, 216);
--color-syntax-comments: rgb(112, 127, 140);
@@ -165,6 +169,10 @@
--nav-scroller-gradient-end: #000;
// syntax
+ --color-syntax-clipboard-bg: rgb(71, 79, 110);
+ --color-syntax-clipboard-hover-bg: rgb(80, 89, 124);
+ --color-syntax-clipboard-check-color: rgb(11, 242, 11);
+
--color-syntax-attributes: rgb(204, 151, 104);
--color-syntax-characters: rgb(217, 201, 124);
--color-syntax-comments: rgb(127, 140, 152);