Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add copy to clipboard in code blocks (#14153)
* feat: add copy to clipboard in code blocks * Use the same style as docusaurus v2 * Remove style from siteConfig.js * Fix typo * Disable button on copied Co-authored-by: Tarun Chauhan <tarun.chauhan@tripjack.com> Co-authored-by: fisker Cheung <lionkay@gmail.com>
- Loading branch information
1 parent
3ef82ae
commit c1b9765
Showing
4 changed files
with
128 additions
and
4 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* "Copy" code block button, style from docusaurus v2 */ | ||
|
||
.code-block-with-actions { | ||
position: relative; | ||
} | ||
|
||
.code-block-actions { | ||
position: absolute; | ||
top: 10px; | ||
right: 10px; | ||
} | ||
|
||
.code-block-copy-button { | ||
width: 32px; | ||
height: 32px; | ||
border: 1px solid #dadde1; | ||
border-radius: 6px; | ||
display: flex; | ||
transition: opacity 0.2s ease-in-out; | ||
opacity: 0; | ||
position: relative; | ||
cursor: pointer; | ||
color: #393a34; | ||
background-color: #f6f8fa; | ||
} | ||
|
||
.code-block-with-actions:hover .code-block-copy-button { | ||
opacity: 0.4; | ||
} | ||
|
||
.code-block-with-actions:hover .code-block-copy-button:hover { | ||
opacity: 1; | ||
} | ||
|
||
.code-block-copy-button__icon { | ||
fill: currentColor; | ||
position: absolute; | ||
width: 18px; | ||
height: 18px; | ||
left: 0; | ||
right: 0; | ||
top: 0; | ||
bottom: 0; | ||
margin: auto; | ||
transition: 0.15s; | ||
} | ||
|
||
.code-block-copy-button__icon--copied { | ||
color: #00d600; | ||
opacity: 0; | ||
transform: scale(0.33); | ||
} | ||
|
||
.code-block-copy-button--copied .code-block-copy-button__icon--copy { | ||
opacity: 0; | ||
transform: scale(0.33); | ||
} | ||
|
||
.code-block-copy-button--copied .code-block-copy-button__icon--copied { | ||
transition-delay: 75ms; | ||
transform: scale(1); | ||
opacity: 1; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* global ClipboardJS */ | ||
|
||
"use strict"; | ||
|
||
(function () { | ||
const CONTAINER_CLASS_NAME = "code-block-with-actions"; | ||
const ACTIONS_CONTAINER_CLASS_NAME = "code-block-actions"; | ||
const COPY_BUTTON_CLASS_NAME = "code-block-copy-button"; | ||
const COPY_BUTTON_COPIED_CLASS_NAME = `${COPY_BUTTON_CLASS_NAME}--copied`; | ||
const COPY_BUTTON_ICON_CLASS_NAME = `${COPY_BUTTON_CLASS_NAME}__icon`; | ||
const COPY_BUTTON_COPY_ICON_CLASS_NAME = `${COPY_BUTTON_ICON_CLASS_NAME}--copy`; | ||
const COPY_BUTTON_COPIED_ICON_CLASS_NAME = `${COPY_BUTTON_ICON_CLASS_NAME}--copied`; | ||
const ARIA_LABEL = "Copy code to clipboard"; | ||
const ARIA_LABEL_COPIED = "Copied"; | ||
|
||
function init(codeBlock) { | ||
const container = codeBlock.parentNode; | ||
container.classList.add(CONTAINER_CLASS_NAME); | ||
|
||
const actionsContainer = Object.assign(document.createElement("div"), { | ||
className: ACTIONS_CONTAINER_CLASS_NAME, | ||
}); | ||
const copyButton = Object.assign(document.createElement("button"), { | ||
className: COPY_BUTTON_CLASS_NAME, | ||
type: "button", | ||
innerHTML: | ||
`<svg class="${COPY_BUTTON_ICON_CLASS_NAME} ${COPY_BUTTON_COPY_ICON_CLASS_NAME}" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg>` + | ||
`<svg class="${COPY_BUTTON_ICON_CLASS_NAME} ${COPY_BUTTON_COPIED_ICON_CLASS_NAME}" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg>`, | ||
}); | ||
copyButton.setAttribute("aria-label", ARIA_LABEL); | ||
|
||
new ClipboardJS(copyButton, { target: () => codeBlock }).on( | ||
"success", | ||
(event) => { | ||
event.clearSelection(); | ||
copyButton.classList.add(COPY_BUTTON_COPIED_CLASS_NAME); | ||
copyButton.setAttribute("aria-label", ARIA_LABEL_COPIED); | ||
copyButton.disabled = true; | ||
|
||
setTimeout(() => { | ||
copyButton.classList.remove(COPY_BUTTON_COPIED_CLASS_NAME); | ||
copyButton.setAttribute("aria-label", ARIA_LABEL); | ||
copyButton.disabled = false; | ||
}, 2000); | ||
} | ||
); | ||
|
||
actionsContainer.appendChild(copyButton); | ||
container.appendChild(actionsContainer); | ||
} | ||
|
||
window.addEventListener("load", () => { | ||
for (const codeBlock of document.querySelectorAll("pre > code.hljs")) { | ||
init(codeBlock); | ||
} | ||
}); | ||
})(); |
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