This is an automated email from the ASF dual-hosted git repository.

gfournier pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-website.git

commit f94b2c77d6ab236c381c1ba9fd21c3b31495f62c
Author: Gaelle Fournier <[email protected]>
AuthorDate: Thu Oct 2 17:29:41 2025 +0200

    feat: add copy to clipboard style
---
 antora-ui-camel/src/css/doc.css                | 100 +++++++++++++++++++++++++
 antora-ui-camel/src/js/06-copy-to-clipboard.js |  65 ++++++++++++++++
 2 files changed, 165 insertions(+)

diff --git a/antora-ui-camel/src/css/doc.css b/antora-ui-camel/src/css/doc.css
index 65200480..e04de163 100644
--- a/antora-ui-camel/src/css/doc.css
+++ b/antora-ui-camel/src/css/doc.css
@@ -616,8 +616,108 @@
   right: 0.25rem;
 }
 
+/* Hide the old language display since we now use source-toolbox */
 .doc .listingblock:hover code[data-lang]::before {
+  display: none;
+}
+
+.doc .source-toolbox {
+  display: flex;
+  visibility: hidden;
+  position: absolute;
+  top: 0.25rem;
+  right: 0.5rem;
+  color: var(--pre-annotation-font-color);
+  font-family: var(--monospace-font-family);
+  font-size: calc(15 / var(--rem-base) * 1rem);
+  font-weight: var(--monospace-font-weight-bold);
+  line-height: 1.2;
+  user-select: none;
+  white-space: nowrap;
+  z-index: 1;
+}
+
+.doc .listingblock:hover .source-toolbox {
+  visibility: visible;
+}
+
+.doc .source-toolbox .source-lang {
+  text-transform: uppercase;
+}
+
+.doc .source-toolbox > :not(:last-child)::after {
+  content: "|";
+  letter-spacing: 0;
+  padding: 0 1ch;
+}
+
+.doc .source-toolbox .copy-button {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  background: none;
+  border: none;
+  color: inherit;
+  outline: none;
+  padding: 0;
+  font-size: inherit;
+  line-height: inherit;
+  width: 1.25em;
+  height: 1.25em;
+  cursor: pointer;
+  position: relative;
+}
+
+.doc .source-toolbox .copy-button::before {
+  content: '';
   display: block;
+  width: 1.25em;
+  height: 1.25em;
+  background-image: url("data:image/svg+xml,%3Csvg 
xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 
16'%3E%3Cpath fill='%23c1c1c1' fill-rule='evenodd' d='M5.75 1a.75.75 0 
00-.75.75v3c0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75v-3a.75.75 0 
00-.75-.75h-4.5zm.75 3V2.5h3V4h-3zm-2.874-.467a.75.75 0 00-.752-1.298A1.75 1.75 
0 002 3.75v9.5c0 .966.784 1.75 1.75 1.75h8.5A1.75 1.75 0 0014 13.25v-9.5a1.75 
1.75 0 00-.874-1.515.75.75 0 10-.752 1.298.25.25 0 01.126.217v9.5a.25.2 [...]
+  background-size: contain;
+  background-repeat: no-repeat;
+  background-position: center;
+  flex-shrink: 0;
+}
+
+.doc .source-toolbox .copy-button.clicked::before {
+  background-image: url("data:image/svg+xml,%3Csvg 
xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 
16'%3E%3Cpath fill='%23c1c1c1' d='M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 
7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 
1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z'/%3E%3C/svg%3E");
+}
+
+.doc .source-toolbox .copy-toast {
+  flex: none;
+  position: relative;
+  display: inline-flex;
+  justify-content: center;
+  margin-top: 1em;
+  background-color: var(--doc-font-color);
+  border-radius: 0.25em;
+  padding: 0.5em;
+  color: var(--color-white);
+  cursor: auto;
+  opacity: 0;
+  transition: opacity 0.5s ease 0.5s;
+}
+
+.doc .source-toolbox .copy-toast::after {
+  content: "";
+  position: absolute;
+  top: 0;
+  width: 1em;
+  height: 1em;
+  border: 0.55em solid transparent;
+  border-left-color: var(--doc-font-color);
+  transform: rotate(-90deg) translateX(50%) translateY(50%);
+  transform-origin: left;
+}
+
+.doc .source-toolbox .copy-button.clicked .copy-toast {
+  opacity: 1;
+  transition: none;
+}
+
+.doc .language-console .hljs-meta {
+  user-select: none;
 }
 
 .doc .dlist dt {
diff --git a/antora-ui-camel/src/js/06-copy-to-clipboard.js 
b/antora-ui-camel/src/js/06-copy-to-clipboard.js
new file mode 100644
index 00000000..c15307d9
--- /dev/null
+++ b/antora-ui-camel/src/js/06-copy-to-clipboard.js
@@ -0,0 +1,65 @@
+;(function () {
+  'use strict'
+
+  var CMD_RX = /^\$ (\S[^\\\n]*(\\\n(?!\$ )[^\\\n]*)*)(?=\n|$)/gm
+  var LINE_CONTINUATION_RX = /( ) *\\\n *|\\\n( ?) */g
+  var TRAILING_SPACE_RX = / +$/gm
+
+  var supportsCopy = window.navigator.clipboard
+
+  ;[].slice.call(document.querySelectorAll('.doc pre.highlight, .doc 
.literalblock pre')).forEach(function (pre) {
+    var code, language, lang, copy, toast, toolbox
+    if (pre.classList.contains('highlight')) {
+      code = pre.querySelector('code')
+      if ((language = code.dataset.lang) && language !== 'console') {
+        ;(lang = document.createElement('span')).className = 'source-lang'
+        lang.appendChild(document.createTextNode(language))
+      }
+    } else if (pre.innerText.startsWith('$ ')) {
+      var block = pre.parentNode.parentNode
+      block.classList.remove('literalblock')
+      block.classList.add('listingblock')
+      pre.classList.add('highlightjs', 'highlight')
+      ;(code = document.createElement('code')).className = 'language-console 
hljs'
+      code.dataset.lang = 'console'
+      code.appendChild(pre.firstChild)
+      pre.appendChild(code)
+    } else {
+      return
+    }
+    ;(toolbox = document.createElement('div')).className = 'source-toolbox'
+    if (lang) toolbox.appendChild(lang)
+    if (supportsCopy) {
+      ;(copy = document.createElement('button')).className = 'copy-button'
+      copy.setAttribute('title', 'Copy to clipboard')
+      copy.setAttribute('aria-label', 'Copy to clipboard')
+      ;(toast = document.createElement('span')).className = 'copy-toast'
+      toast.appendChild(document.createTextNode('Copied!'))
+      copy.appendChild(toast)
+      toolbox.appendChild(copy)
+    }
+    pre.appendChild(toolbox)
+    if (copy) copy.addEventListener('click', writeToClipboard.bind(copy, code))
+  })
+
+  function extractCommands (text) {
+    var cmds = []
+    var m
+    while ((m = CMD_RX.exec(text))) 
cmds.push(m[1].replace(LINE_CONTINUATION_RX, '$1$2'))
+    return cmds.join(' && ')
+  }
+
+  function writeToClipboard (code) {
+    var text = code.innerText.replace(TRAILING_SPACE_RX, '')
+    if (code.dataset.lang === 'console' && text.startsWith('$ ')) text = 
extractCommands(text)
+    window.navigator.clipboard.writeText(text).then(
+      function () {
+        this.classList.add('clicked')
+        setTimeout(function () {
+          this.classList.remove('clicked')
+        }.bind(this), 1000)
+      }.bind(this),
+      function () {}
+    )
+  }
+})()

Reply via email to