Merge pull request #2375 from pikasTech/fix/2369-mdtodo-layout-toggle

fix: 折叠按钮移到主header,避免左侧折叠压缩主区域
This commit is contained in:
Lyon
2026-07-04 02:45:33 +08:00
committed by GitHub
3 changed files with 28 additions and 20 deletions
@@ -49,18 +49,17 @@ const clampedLeftWidth = computed(() => clamp(props.leftWidth, props.minLeftWidt
const clampedRightWidth = computed(() => clamp(props.rightWidth, props.minRightWidth, props.maxRightWidth));
const layoutStyle = computed(() => {
const leftColumn = props.leftCollapsed
? `${props.leftCollapsedWidth}px`
const leftCol = props.leftCollapsed
? '0px'
: `minmax(${props.leftCollapsedWidth}px, ${clampedLeftWidth.value}%)`;
const leftResizerCol = props.leftCollapsed ? '0px' : '6px';
if (!props.rightOpen) {
const leftCol = props.leftCollapsed ? '0px' : leftColumn;
const resizerCol = props.leftCollapsed ? '0px' : '6px';
return { gridTemplateColumns: `${leftCol} ${resizerCol} minmax(0, 1fr)` };
return { gridTemplateColumns: `${leftCol} ${leftResizerCol} minmax(0, 1fr)` };
}
const mainShare = props.rightCollapsed ? "minmax(0, 1fr)" : `minmax(0, ${100 - clampedRightWidth.value}fr)`;
const rightResizeColumn = props.rightCollapsed ? "0" : "6px";
const rightColumn = props.rightCollapsed ? "0px" : `minmax(280px, ${clampedRightWidth.value}fr)`;
return { gridTemplateColumns: `${leftColumn} 6px ${mainShare} ${rightResizeColumn} ${rightColumn}` };
return { gridTemplateColumns: `${leftCol} ${leftResizerCol} ${mainShare} ${rightResizeColumn} ${rightColumn}` };
});
onBeforeUnmount(() => stopResize());
@@ -109,12 +108,9 @@ function clamp(value: number, min: number, max: number): number {
:data-right-collapsed="rightCollapsed"
:data-resizing="resizing || undefined"
>
<aside v-if="!leftCollapsed" class="split-workspace-pane split-workspace-left" :data-collapsed="leftCollapsed">
<aside class="split-workspace-pane split-workspace-left" :data-collapsed="leftCollapsed">
<slot name="left" />
</aside>
<button v-if="leftCollapsed" class="split-workspace-toggle split-workspace-toggle-left" type="button" aria-label="展开左侧面板" @click="$emit('update:leftCollapsed', false)">
<slot name="left-toggle"></slot>
</button>
<div
class="split-workspace-resizer split-workspace-resizer-left"
:data-testid="leftResizerTestId"
@@ -135,12 +131,9 @@ function clamp(value: number, min: number, max: number): number {
:aria-valuenow="Math.round(clampedRightWidth)"
@pointerdown="startResize('right', $event)"
/>
<aside v-if="rightOpen && !rightCollapsed" class="split-workspace-pane split-workspace-right" :data-collapsed="rightCollapsed">
<aside v-if="rightOpen" class="split-workspace-pane split-workspace-right" :data-collapsed="rightCollapsed">
<slot name="right" />
</aside>
<button v-if="rightOpen && rightCollapsed" class="split-workspace-toggle split-workspace-toggle-right" type="button" aria-label="展开右侧面板" @click="$emit('update:rightCollapsed', false)">
<slot name="right-toggle"></slot>
</button>
</section>
</template>
@@ -192,6 +185,11 @@ function clamp(value: number, min: number, max: number): number {
display: none;
}
.split-workspace-left[data-collapsed="true"],
.split-workspace-right[data-collapsed="true"] {
overflow: hidden;
}
.split-workspace-layout[data-resizing] {
user-select: none;
}
@@ -212,11 +210,6 @@ function clamp(value: number, min: number, max: number): number {
align-self: stretch;
}
.split-workspace-toggle { display: inline-flex; width: 28px; height: 100%; align-items: center; justify-content: center; border: 1px solid #d8e1e7; border-radius: 0; background: #f8fafb; color: #5d6a73; cursor: pointer; font-size: 16px; font-weight: 850; }
.split-workspace-toggle:hover { background: #eef2f5; color: #111827; }
.split-workspace-toggle-left { border-right: 0; }
.split-workspace-toggle-right { border-left: 0; }
@media (max-width: 720px) {
.split-workspace-layout {
display: grid;
@@ -526,6 +526,16 @@ function setError(err: unknown): void {
<p v-if="source.sourceError.value" class="source-error" data-testid="mdtodo-source-error">{{ source.sourceError.value }}</p>
</div>
<div class="mdtodo-toggle-bar">
<button class="mdtodo-toggle-btn mdtodo-toggle-left" type="button" :data-testid="taskPaneCollapsed ? 'mdtodo-expand-left' : 'mdtodo-collapse-left'" :aria-label="taskPaneCollapsed ? '展开左侧面板' : '收起左侧面板'" @click="taskPaneCollapsed = !taskPaneCollapsed">
{{ taskPaneCollapsed ? '' : '' }}
</button>
<span class="mdtodo-toggle-spacer" />
<button v-if="reportPaneOpen" class="mdtodo-toggle-btn mdtodo-toggle-right" type="button" :data-testid="reportPaneCollapsed ? 'mdtodo-expand-right' : 'mdtodo-collapse-right'" :aria-label="reportPaneCollapsed ? '展开右侧面板' : '收起右侧面板'" @click="reportPaneCollapsed = !reportPaneCollapsed">
{{ reportPaneCollapsed ? '' : '' }}
</button>
</div>
<SplitWorkspaceLayout
v-model:left-width="taskPaneWidth"
v-model:right-width="reportPaneWidth"
@@ -686,4 +696,10 @@ function setError(err: unknown): void {
.source-error { border: 1px solid #fecaca; background: #fef2f2; color: #991b1b; }
.mdtodo-workspace { grid-row: 3; min-height: 0; height: 100%; max-height: none; align-self: stretch; }
.mdtodo-error { display: grid; align-content: start; gap: 12px; padding: 12px; overflow: auto; }
.mdtodo-toggle-bar { display: flex; align-items: center; gap: 4px; min-width: 0; border-bottom: 1px solid #d8e1e7; background: #f8fafb; padding: 2px 8px; }
.mdtodo-toggle-btn { display: inline-flex; width: 26px; height: 26px; align-items: center; justify-content: center; border: 1px solid #cbd6dd; border-radius: 4px; background: #fff; color: #5d6a73; cursor: pointer; font-size: 11px; font-weight: 850; line-height: 1; }
.mdtodo-toggle-btn:hover { background: #eef2f5; color: #111827; border-color: #a7b8c4; }
.mdtodo-toggle-spacer { flex: 1; min-width: 0; }
</style>
@@ -62,7 +62,6 @@ function toggleTask(task: MdtodoTaskRecord): void {
<span v-if="!collapsed">同步中</span>
</span>
<button class="icon-button" type="button" data-testid="mdtodo-new-task-open" aria-label="新建任务" @click="emit('openCreateTask')">+</button>
<button class="icon-button" type="button" data-testid="mdtodo-task-pane-toggle" :aria-label="collapsed ? '展开任务树' : '收起任务树'" @click="emit('update:collapsed', !collapsed)">{{ collapsed ? '' : '' }}</button>
</div>
</header>
<template v-if="!collapsed">