Skip to content

Commit 6a812e0

Browse files
feat(copy-code): make markdown code block copy button fixed to top-right corner (#76)
* feat(copy-code): enhance copy button injection and styling for better UX * feat(copy-code): prevent copy button injection for Mermaid code blocks --------- Co-authored-by: Miguel Machado <hello@miguelmachado.dev>
1 parent bf00250 commit 6a812e0

1 file changed

Lines changed: 27 additions & 16 deletions

File tree

packages/ui/src/Markdown/plugins/copy-code-to-clipboard.js

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -90,30 +90,41 @@ export function copyCodeToClipboardPlugin() {
9090
if (!codeElement.innerHTML) return;
9191

9292
const pre = codeElement.parentElement;
93-
if (pre.childElementCount > 1) return;
93+
if (pre.dataset.copyButtonInjected === 'true') return;
94+
95+
const isMermaidBlock = codeElement.classList.contains('language-mermaid') || pre.classList.contains('mermaid');
96+
97+
if (isMermaidBlock) return;
9498

9599
const codeToCopy = codeElement.innerText;
96100

97-
const externalDivElement = document.createElement('div');
98-
setStyleProperties(externalDivElement, {
101+
const wrapper = document.createElement('div');
102+
wrapper.classList.add('copy-code-wrapper');
103+
104+
const preComputedStyle = window.getComputedStyle(pre);
105+
setStyleProperties(wrapper, {
99106
position: 'relative',
100-
top: '-6px',
101-
right: '-6px',
102-
'min-width': '32px',
103-
});
104-
setStyleProperties(pre, {
105-
display: 'flex',
106-
'justify-content': 'space-between',
107-
gap: '4px',
107+
'margin-top': preComputedStyle.marginTop,
108+
'margin-bottom': preComputedStyle.marginBottom,
108109
});
109110

110-
pre.appendChild(externalDivElement);
111+
const existingPaddingRight = parseFloat(preComputedStyle.paddingRight) || 0;
112+
pre.style.paddingRight = `${existingPaddingRight + 40}px`;
113+
114+
pre.parentNode.insertBefore(wrapper, pre);
115+
wrapper.appendChild(pre);
116+
117+
const buttonWrapper = document.createElement('div');
118+
setStyleProperties(buttonWrapper, {
119+
position: 'absolute',
120+
top: '8px',
121+
right: '8px',
122+
});
111123

112-
const internalDivElement = document.createElement('div');
113-
internalDivElement.style.position = 'absolute';
114-
externalDivElement.appendChild(internalDivElement);
124+
wrapper.appendChild(buttonWrapper);
125+
createCopyButton(buttonWrapper, codeToCopy);
115126

116-
createCopyButton(internalDivElement, codeToCopy);
127+
pre.dataset.copyButtonInjected = 'true';
117128
});
118129
},
119130
};

0 commit comments

Comments
 (0)