fix(layout): 侧边栏置顶,文档标签栏移到侧边栏右侧
TabBar 从菜单栏下方的整行移入主区右侧内容列(新增 .content-col 纵向容器), 侧边栏自此从菜单栏下方贯通到状态栏;隐藏侧边栏时标签栏占满整行。 打印规则同步覆盖新容器。无头浏览器实测:标签栏左边缘与侧边栏右边缘对齐 (250px)。vitest 87 通过 + 2 跳过,tsc 与构建通过。
This commit is contained in:
28
src/App.tsx
28
src/App.tsx
@@ -1150,19 +1150,6 @@ export default function App() {
|
||||
<div className="app">
|
||||
<TitleBar docTitle={tab?.title ?? 'new-markdown'} dirty={tab ? isDirty(tab) : false} />
|
||||
<MenuBar menus={menus} />
|
||||
<TabBar
|
||||
tabs={state.tabs}
|
||||
activeId={state.activeId}
|
||||
onActivate={(id) => { dispatch({ type: 'activate', id }); setSourceMode(false) }}
|
||||
onClose={closeTab}
|
||||
onCloseOthers={(id) => requestClose(state.tabs.filter((t) => t.id !== id).map((t) => t.id), () => dispatch({ type: 'closeOthers', id }))}
|
||||
onCloseRight={(id) => {
|
||||
const idx = state.tabs.findIndex((t) => t.id === id)
|
||||
requestClose(state.tabs.slice(idx + 1).map((t) => t.id), () => dispatch({ type: 'closeRight', id }))
|
||||
}}
|
||||
onNew={newDoc}
|
||||
onMove={(id, toIndex) => dispatch({ type: 'move', id, toIndex })}
|
||||
/>
|
||||
<div className="main">
|
||||
{ui.sidebar && (
|
||||
<div style={{ width: ui.sidebarWidth, flex: 'none', display: 'flex' }}>
|
||||
@@ -1185,6 +1172,20 @@ export default function App() {
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="content-col">
|
||||
<TabBar
|
||||
tabs={state.tabs}
|
||||
activeId={state.activeId}
|
||||
onActivate={(id) => { dispatch({ type: 'activate', id }); setSourceMode(false) }}
|
||||
onClose={closeTab}
|
||||
onCloseOthers={(id) => requestClose(state.tabs.filter((t) => t.id !== id).map((t) => t.id), () => dispatch({ type: 'closeOthers', id }))}
|
||||
onCloseRight={(id) => {
|
||||
const idx = state.tabs.findIndex((t) => t.id === id)
|
||||
requestClose(state.tabs.slice(idx + 1).map((t) => t.id), () => dispatch({ type: 'closeRight', id }))
|
||||
}}
|
||||
onNew={newDoc}
|
||||
onMove={(id, toIndex) => dispatch({ type: 'move', id, toIndex })}
|
||||
/>
|
||||
<div className="editor-area" style={{ ['--doc-zoom' as string]: zoom }}>
|
||||
{!tab && (
|
||||
<div className="empty-state">
|
||||
@@ -1284,6 +1285,7 @@ export default function App() {
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<StatusBar
|
||||
words={statusCounts.words}
|
||||
|
||||
@@ -56,7 +56,9 @@ button { font: inherit; color: inherit; }
|
||||
.menu-divider { height: 1px; background: var(--border); margin: 5px 8px; }
|
||||
|
||||
/* 标签栏 */
|
||||
.tabbar { display: flex; align-items: stretch; background: var(--bg-panel); border-bottom: 1px solid var(--border); min-height: 36px; overflow-x: auto; }
|
||||
.tabbar { display: flex; align-items: stretch; background: var(--bg-panel); border-bottom: 1px solid var(--border); min-height: 36px; overflow-x: auto; flex: none; }
|
||||
/* 左侧栏置顶、文档标签栏移到侧边栏右侧的内容列顶部 */
|
||||
.content-col { flex: 1; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
|
||||
.tab { display: flex; align-items: center; gap: 7px; padding: 0 8px 0 14px; font-size: 13px; cursor: pointer; border-right: 1px solid var(--border); white-space: nowrap; color: var(--text-dim); }
|
||||
.tab.active { background: var(--bg-editor); color: var(--text); box-shadow: inset 0 2px 0 var(--accent); }
|
||||
.tab-title { max-width: 180px; overflow: hidden; text-overflow: ellipsis; }
|
||||
@@ -95,7 +97,7 @@ button { font: inherit; color: inherit; }
|
||||
.tree-icon { color: var(--text-dim); width: 12px; flex: none; }
|
||||
|
||||
.editor-scroll { flex: 1; overflow-y: auto; background: var(--bg-editor); min-width: 0; position: relative; }
|
||||
.editor-area { flex: 1; display: flex; min-width: 0; position: relative; }
|
||||
.editor-area { flex: 1; display: flex; min-width: 0; min-height: 0; position: relative; }
|
||||
/* 标签保活后每个窗格自带滚动容器,各自保留滚动位置;窗格加载状态覆盖层 */
|
||||
.pane-loading { position: absolute; inset: 0; display: flex; flex-direction: column; gap: 12px; align-items: center; justify-content: center; color: var(--text-dim); font-size: 13px; background: var(--doc-paper); z-index: 5; }
|
||||
.pane-spinner { width: 26px; height: 26px; border-radius: 50%; border: 3px solid var(--border); border-top-color: var(--accent); animation: pane-spin 0.8s linear infinite; }
|
||||
@@ -269,7 +271,7 @@ kbd { background: var(--code-bg); border: 1px solid var(--border); border-radius
|
||||
@media print {
|
||||
.titlebar, .menubar, .tabbar, .sidebar, .statusbar, .modal-backdrop, .app-notice, .context-menu,
|
||||
.table-toolbar, .tree-context-menu, .findbar, .mermaid-head { display: none !important; }
|
||||
.app, .main, .editor-scroll { display: block !important; height: auto !important; overflow: visible !important; }
|
||||
.app, .main, .content-col, .editor-area, .editor-scroll { display: block !important; height: auto !important; overflow: visible !important; }
|
||||
.editor-scroll { background: #fff !important; }
|
||||
/* 打印只出活动窗格:保活的隐藏窗格不能被上面的 display:block 通杀带出来 */
|
||||
.editor-scroll.tab-pane { display: none !important; }
|
||||
|
||||
Reference in New Issue
Block a user