write(ui): 三栏宽度可拖拽 + localStorage 持久化
deploy articulate / build-and-deploy (push) Successful in 1m15s
deploy cube / build-and-deploy (push) Successful in 1m40s
deploy karaoke / build-and-deploy (push) Successful in 1m6s
deploy llm-proxy / build-and-deploy (push) Successful in 2m3s
deploy music / build-and-deploy (push) Successful in 2m16s
deploy notes / build-and-deploy (push) Successful in 2m2s
deploy simpleasm / build-and-deploy (push) Successful in 1m30s
deploy werewolf / build-and-deploy (push) Successful in 1m12s
deploy write / build-and-deploy (push) Successful in 1m54s

- sidebar | workspace 拖拽条:调整侧栏宽(180-500px)
- editor | preview 拖拽条:调整源码/预览比例(15%-85%)
- CSS var --sidebar-w / --editor-fr / --preview-fr 驱动 grid-template-columns
- 鼠标 down 开始 drag,move 实时算 px/dx,up 落盘 localStorage
- 移动端(<768px)自动隐藏拖拽条,回到 100% 切 tab 模式
This commit is contained in:
Fam Zheng
2026-05-24 17:18:37 +01:00
parent 9328c01c1b
commit 7b868852d2
4 changed files with 270 additions and 9 deletions
+59
View File
@@ -14,6 +14,62 @@ const statusErr = ref(false)
const busy = ref(false)
const recording = ref(false)
onMounted(() => applyLayoutVars())
// ====== 拖拽布局:sidebar 宽(px + editor/preview 比例(0-1======
const sidebarW = ref(parseInt(localStorage.getItem('write.sidebarW') || '260'))
const editorRatio = ref(parseFloat(localStorage.getItem('write.editorRatio') || '0.5'))
function applyLayoutVars(): void {
const r = document.documentElement
r.style.setProperty('--sidebar-w', sidebarW.value + 'px')
r.style.setProperty('--editor-fr', editorRatio.value + 'fr')
r.style.setProperty('--preview-fr', (1 - editorRatio.value) + 'fr')
}
let dragKind: 'sidebar' | 'editor' | null = null
let dragStartX = 0
let dragStartVal = 0
let dragPaneW = 0
function startDrag(e: MouseEvent, kind: 'sidebar' | 'editor'): void {
dragKind = kind
dragStartX = e.clientX
if (kind === 'sidebar') {
dragStartVal = sidebarW.value
} else {
dragStartVal = editorRatio.value
const pane = (e.currentTarget as HTMLElement).parentElement
dragPaneW = pane ? pane.offsetWidth : window.innerWidth
}
document.body.style.cursor = 'col-resize'
document.body.style.userSelect = 'none'
window.addEventListener('mousemove', onDrag)
window.addEventListener('mouseup', endDrag)
e.preventDefault()
}
function onDrag(e: MouseEvent): void {
if (!dragKind) return
const dx = e.clientX - dragStartX
if (dragKind === 'sidebar') {
sidebarW.value = Math.max(180, Math.min(500, dragStartVal + dx))
} else {
const newR = dragStartVal + dx / Math.max(1, dragPaneW)
editorRatio.value = Math.max(0.15, Math.min(0.85, newR))
}
applyLayoutVars()
}
function endDrag(): void {
if (!dragKind) return
localStorage.setItem('write.sidebarW', String(sidebarW.value))
localStorage.setItem('write.editorRatio', String(editorRatio.value))
dragKind = null
document.body.style.cursor = ''
document.body.style.userSelect = ''
window.removeEventListener('mousemove', onDrag)
window.removeEventListener('mouseup', endDrag)
}
const needToken = ref(!getToken())
const tokenInput = ref('')
@@ -218,6 +274,8 @@ onMounted(() => {
<div class="sidebar-backdrop" @click="drawerOpen = false"></div>
<div class="splitter splitter-main" @mousedown="startDrag($event, 'sidebar')" title="拖动调整侧栏宽度"></div>
<aside class="sidebar">
<div class="sidebar-header">
<h1> write</h1>
@@ -256,6 +314,7 @@ onMounted(() => {
:disabled="activeId === null"
></textarea>
</div>
<div class="splitter splitter-editor" @mousedown="startDrag($event, 'editor')" title="拖动调整源码/预览比例"></div>
<div class="preview" v-html="renderedPreview"></div>
</div>