97 lines
3.4 KiB
Vue
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> |