diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index ee593e568f4..33f75f09314 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -1,6 +1,7 @@ const path = require("path"); const math = require("remark-math"); const katex = require("rehype-katex"); + const { versions, versionedPages, versionedCategories } = require("./dbt-versions"); require("dotenv").config(); @@ -258,6 +259,8 @@ var siteSettings = { src: "https://cdn.jsdelivr.net/npm/featherlight@1.7.14/release/featherlight.min.js", defer: true, }, + "https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js", + "/js/headerLinkCopy.js", "/js/gtm.js", "/js/onetrust.js", "https://kit.fontawesome.com/7110474d41.js", diff --git a/website/src/css/custom.css b/website/src/css/custom.css index fc51ef8a8ef..1feb5510cc5 100644 --- a/website/src/css/custom.css +++ b/website/src/css/custom.css @@ -2034,6 +2034,45 @@ html[data-theme="dark"] .theme-doc-sidebar-container>div>button.button:hover { color: #818589; /* You can adjust the color as needed */ } +h3.anchor a.hash-link:before, +h2.anchor a.hash-link:before { + content: ""; + background-image: url('/img/copy.png'); + background-size: 18px 18px; + height: 18px; + width: 18px; + display: inline-block; +} + +h3.anchor.clicked a.hash-link:before, +h2.anchor.clicked a.hash-link:before { + background-image: url('/img/check.png'); + background-size: 18px 13px; + height: 13px; +} + +.copy-popup { + position: fixed; + top: 10px; + left: 50%; + transform: translateX(-50%); + background-color: #047377; + color: rgb(236, 236, 236); + padding: 10px; + border-radius: 5px; + z-index: 9999; +} + +.close-button { + cursor: pointer; + margin: 0 10px; + font-size: 20px; +} + +.close-button:hover { + color: #fff; /* Change color on hover if desired */ +} + @media (max-width: 996px) { .quickstart-container { flex-direction: column; diff --git a/website/static/img/check.png b/website/static/img/check.png new file mode 100644 index 00000000000..91192b50cb1 Binary files /dev/null and b/website/static/img/check.png differ diff --git a/website/static/img/copy.png b/website/static/img/copy.png new file mode 100644 index 00000000000..6b0f5f086c7 Binary files /dev/null and b/website/static/img/copy.png differ diff --git a/website/static/js/headerLinkCopy.js b/website/static/js/headerLinkCopy.js new file mode 100644 index 00000000000..a41f4f4e7ce --- /dev/null +++ b/website/static/js/headerLinkCopy.js @@ -0,0 +1,58 @@ +/* eslint-disable */ + + // Get all the headers with anchor links. + // The 'click' event worked over 'popstate' because click captures page triggers, as well as back/forward button triggers + // Adding the 'load' event to also capture the initial page load + window.addEventListener("click", copyHeader); + window.addEventListener("load", copyHeader); + + // separating function from eventlistener to understand they are two separate things + function copyHeader () { + const headers = document.querySelectorAll("h2.anchor, h3.anchor"); + +headers.forEach((header) => { + header.style.cursor = "pointer"; + const clipboard = new ClipboardJS(header, { + text: function(trigger) { + const anchorLink = trigger.getAttribute("id"); + return window.location.href.split('#')[0] + '#' + anchorLink; + } + }); + + clipboard.on('success', function(e) { + // Provide user feedback (e.g., alert or tooltip) here + const popup = document.createElement('div'); + popup.classList.add('copy-popup'); + popup.innerText = 'Link copied!'; + document.body.appendChild(popup); + + // Set up timeout to remove the popup after 3 seconds + setTimeout(() => { + document.body.removeChild(popup); + }, 3000); + + // Add close button ('x') + const closeButton = document.createElement('span'); + closeButton.classList.add('close-button'); + closeButton.innerHTML = ' ×'; // '×' symbol for 'x' + closeButton.addEventListener('click', () => { + if (document.body.contains(popup)) { + document.body.removeChild(popup); + } + }); + popup.appendChild(closeButton); + + // Add and remove the 'clicked' class for styling purposes + e.trigger.classList.add("clicked"); + setTimeout(() => { + if (document.body.contains(popup)) { + document.body.removeChild(popup); + } + }, 3000); + }); + + clipboard.on('error', function(e) { + console.error("Unable to copy to clipboard: " + e.text); + }); +}); +};