Files
nl-blogs/client/src/components/SnippetModal.vue
2026-01-15 13:51:44 +08:00

97 lines
3.4 KiB
Vue

<template>
<div id="snippet-modal" class="fixed inset-0 z-[100] modal-overlay hidden flex items-center justify-center p-4 md:p-10 opacity-0 transition-opacity duration-300">
<div class="bg-[#0a0a0c] border border-white/10 w-full max-w-6xl h-full md:h-[80vh] rounded-2xl flex flex-col overflow-hidden shadow-2xl transform scale-95 transition-transform duration-300" id="modal-content">
<div class="h-16 border-b border-white/10 flex items-center justify-between px-6 bg-white/5">
<div class="flex items-center gap-3"><i data-lucide="code-2" class="text-art-accent"></i><span class="font-bold text-white" id="modal-title">{{ modalTitle }}</span></div>
<button @click="closeSnippet" class="p-2 hover:bg-white/10 rounded-full text-white/50 hover:text-white transition-colors"><i data-lucide="x" class="w-5 h-5"></i></button>
</div>
<div class="flex-1 overflow-hidden">
<!-- 使用CodePreview组件 -->
<CodePreview
:initial-code="modalCode"
:initial-language="detectLanguage(modalCode)"
@code-change="handleCodeChange"
@language-change="handleLanguageChange"
/>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import CodePreview from './CodePreview.vue'
const modalTitle = ref('Code')
const modalCode = ref('')
// 检测代码语言
const detectLanguage = (code: string): string => {
// 简单的语言检测逻辑,可以根据需要扩展
if (code.includes('<html') || code.includes('<div') || code.includes('<body')) {
return 'html'
} else if (code.includes('import React') || code.includes('React.')) {
return 'react'
} else if (code.includes('<template') || code.includes('export default')) {
return 'vue'
} else if (code.includes('class ') && code.includes('{')) {
return 'typescript'
} else if (code.includes('function ') || code.includes('const ') || code.includes('let ') || code.includes('var ')) {
return 'javascript'
} else if (code.includes('@import') || code.includes('{') && code.includes(':') && code.includes(';')) {
return 'css'
} else if (code.includes('print(') || code.includes('def ')) {
return 'python'
} else {
return 'html'
}
}
const showSnippet = (title: string, code: string) => {
modalTitle.value = title
modalCode.value = code
const modal = document.getElementById('snippet-modal')
if (modal) {
modal.classList.remove('hidden')
modal.classList.add('flex')
setTimeout(() => {
modal.style.opacity = '1'
const content = document.getElementById('modal-content')
if (content) {
content.style.transform = 'scale(1)'
}
}, 10)
document.body.style.overflow = 'hidden'
}
}
const closeSnippet = () => {
const modal = document.getElementById('snippet-modal')
if (modal) {
modal.style.opacity = '0'
const content = document.getElementById('modal-content')
if (content) {
content.style.transform = 'scale(0.95)'
}
setTimeout(() => {
modal.classList.remove('flex')
modal.classList.add('hidden')
document.body.style.overflow = ''
}, 300)
}
}
const handleCodeChange = (newCode: string) => {
modalCode.value = newCode
}
const handleLanguageChange = (newLanguage: string) => {
// 可以在这里处理语言变化事件
console.log('Language changed to:', newLanguage)
}
// 暴露方法给全局使用
window.showSnippet = showSnippet
window.closeSnippet = closeSnippet
</script>