Skip to content

Commit 80fffa9

Browse files
authored
fix: code blocks and copy button (#408)
1 parent e602dc7 commit 80fffa9

File tree

1 file changed

+38
-14
lines changed

1 file changed

+38
-14
lines changed

packages/app/app/components/Commits.vue

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,9 @@ const selectedCommit = shallowRef<
4444
(typeof commitsWithRelease.value)[number] | null
4545
>(null);
4646
47-
// Markdown
48-
49-
// Add target to links
50-
51-
const colorMode = useColorMode();
5247
let shiki: HighlighterCore;
5348
5449
onBeforeMount(async () => {
55-
// if (typeof window === 'undefined') {
56-
// const { loadWasm } = await import('shiki')
57-
// // @ts-expect-error ignore error
58-
// await loadWasm(import(/* @vite-ignore */ 'shiki/onig.wasm'))
59-
// }
60-
6150
shiki = createHighlighterCoreSync({
6251
themes: [githubDark, githubLight],
6352
langs: [bash],
@@ -73,10 +62,45 @@ onBeforeMount(async () => {
7362
);
7463
},
7564
code({ text }) {
76-
return `<code class="language-bash">${shiki.codeToHtml(text, {
77-
theme: colorMode.preference === "dark" ? "github-dark" : "github-light",
65+
const currentTheme = document.documentElement.classList.contains("dark")
66+
? "github-dark"
67+
: "github-light";
68+
const highlightedCode = shiki.codeToHtml(text, {
69+
theme: currentTheme,
7870
lang: "bash",
79-
})}</code>`;
71+
});
72+
73+
function copyCodeHandler(this: HTMLButtonElement, codeText: string) {
74+
navigator.clipboard?.writeText(codeText);
75+
if (this.dataset.timeoutId) {
76+
clearTimeout(parseInt(this.dataset.timeoutId));
77+
}
78+
this.textContent = "Copied!";
79+
this.classList.add("!text-green-600", "dark:!text-green-400");
80+
const timeoutId = setTimeout(() => {
81+
this.textContent = "Copy";
82+
this.classList.remove("!text-green-600", "dark:!text-green-400");
83+
delete this.dataset.timeoutId;
84+
}, 2000);
85+
this.dataset.timeoutId = timeoutId.toString();
86+
}
87+
88+
return `
89+
<div class="relative group my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-gray-700 shadow-sm">
90+
<div class="flex items-center justify-end px-4 py-1 bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700">
91+
<button
92+
onclick='(${copyCodeHandler.toString()}).call(this, ${JSON.stringify(text)})'
93+
class="px-2 py-1 text-xs text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors opacity-0 group-hover:opacity-100"
94+
title="Copy to clipboard"
95+
>
96+
Copy
97+
</button>
98+
</div>
99+
<div class="overflow-x-auto">
100+
<div class="[&>pre]:!my-0 [&>pre]:!bg-transparent [&>pre]:!border-0 [&>pre]:!rounded-none [&>pre]:!p-4">${highlightedCode}</div>
101+
</div>
102+
</div>
103+
`;
80104
},
81105
};
82106

0 commit comments

Comments
 (0)