feat: 新增代码块增强组件(支持复制与语言标签)
This commit is contained in:
parent
d79e66facc
commit
5e9220302c
71
src/components/CodeBlockHelper.astro
Normal file
71
src/components/CodeBlockHelper.astro
Normal file
@ -0,0 +1,71 @@
|
||||
---
|
||||
// 此组件不渲染任何 HTML,仅注入全局客户端脚本
|
||||
---
|
||||
<script>
|
||||
function upgradeCodeBlocks() {
|
||||
const codeBlocks = document.querySelectorAll('pre');
|
||||
|
||||
codeBlocks.forEach((pre) => {
|
||||
// 防止重复注入
|
||||
if (pre.querySelector('.copy-button')) return;
|
||||
|
||||
// 1. 获取语言名称 (从 rehype-pretty-code 自动生成的属性中获取)
|
||||
const lang = pre.getAttribute('data-language') || 'code';
|
||||
|
||||
// 2. 创建包裹容器并调整 pre 样式
|
||||
pre.classList.add('relative', 'group');
|
||||
|
||||
// 3. 创建顶栏 (语言标签 + 复制按钮)
|
||||
const header = document.createElement('div');
|
||||
header.className = "absolute top-0 right-0 left-0 flex justify-between items-center px-4 py-1.5 text-[10px] font-mono font-bold uppercase tracking-widest text-gray-400 bg-gray-800/50 border-b border-gray-700/50 rounded-t-lg opacity-0 group-hover:opacity-100 transition-opacity duration-300";
|
||||
header.innerHTML = `
|
||||
<span class="flex items-center gap-1.5"><span class="w-2 h-2 rounded-full bg-blue-500"></span>${lang}</span>
|
||||
<button class="copy-button hover:text-white transition-colors cursor-pointer flex items-center gap-1">
|
||||
<span class="btn-text">COPY</span>
|
||||
</button>
|
||||
`;
|
||||
|
||||
// 4. 注入到 pre 头部
|
||||
pre.prepend(header);
|
||||
// 增加 padding 给 header 留位
|
||||
pre.style.paddingTop = '2.5rem';
|
||||
|
||||
// 5. 绑定点击事件
|
||||
const btn = header.querySelector('.copy-button');
|
||||
const btnText = header.querySelector('.btn-text');
|
||||
|
||||
btn?.addEventListener('click', async () => {
|
||||
const code = pre.querySelector('code')?.innerText || "";
|
||||
await navigator.clipboard.writeText(code);
|
||||
|
||||
if (btnText) {
|
||||
btnText.innerText = "COPIED!";
|
||||
btn.classList.add('text-green-400');
|
||||
setTimeout(() => {
|
||||
btnText.innerText = "COPY";
|
||||
btn.classList.remove('text-green-400');
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 初始化
|
||||
document.addEventListener('astro:page-load', upgradeCodeBlocks);
|
||||
upgradeCodeBlocks();
|
||||
</script>
|
||||
|
||||
<style is:global>
|
||||
/* 优化代码块圆角与阴影 */
|
||||
pre {
|
||||
@apply rounded-xl shadow-2xl border border-gray-800/50 !important;
|
||||
}
|
||||
/* 隐藏原有的滚动条,美化自定义滚动条 */
|
||||
pre::-webkit-scrollbar {
|
||||
height: 5px;
|
||||
}
|
||||
pre::-webkit-scrollbar-thumb {
|
||||
background: #374151;
|
||||
border-radius: 10px;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user