20260825224435

This commit is contained in:
oneao committed 2026-08-25 22:44:36 +08:00
1 parent a509f93f34
commit 9957757b5d
146 files changed
+148 -682

No files matched your search

+9 -16
View File
@@ -95,15 +95,13 @@ function onSplitterResize(sizes) {
:min="appStore.sidebarCollapsed ? undefined : SIDEBAR_MIN"
:max="appStore.sidebarCollapsed ? undefined : SIDEBAR_MAX"
:resizable="!appStore.sidebarCollapsed"
class="fms-sidebar-panel"
>
<AppSidebar />
</SplitterPanel>
<!-- 主区面板:顶栏(已含多页签)独立在灰底上,下方一张白卡放内容 -->
<!-- 主区面板:顶栏(含页签)独立在灰底上,下方一张白卡放内容 -->
<SplitterPanel class="fms-main-panel">
<div class="fms-main-col">
<!-- 顶栏已合并多页签,主区只留内容白卡 -->
<AppTopbar />
<div class="fms-main">
@@ -192,7 +190,7 @@ function onSplitterResize(sizes) {
}
/* 主区面板:四周留 8px 间距(含左侧),与侧栏拉开标准间隙。
* 折叠态(窄侧栏 48px)左侧归 0,白卡贴侧栏右缘 */
* 折叠态(窄侧栏 48px)左侧归 0,避免过窄时两侧都留间隙 */
.fms-main-panel {
padding: 8px;
}
@@ -201,16 +199,6 @@ function onSplitterResize(sizes) {
padding: 8px 8px 8px 0;
}
/* 侧栏面板:四周留 8px,白色侧栏卡浮在灰底上(与顶栏同一套间距) */
.fms-sidebar-panel {
padding: 8px;
box-sizing: border-box;
}
.fms-layout.is-collapsed .fms-sidebar-panel {
padding: 8px 8px 8px 0;
}
/* 覆盖 Splitter 面板默认 overflow: auto(scoped 同名规则特异性更高,需带 .fms-layout 提权),
* 让主卡片左侧阴影完整绘制到侧栏背景上(对齐 old2 的 z-index 效果) */
.fms-layout .fms-splitter-panel.fms-main-panel {
@@ -227,7 +215,8 @@ function onSplitterResize(sizes) {
gap: 8px;
}
/* 主区:透明容器(不再包白卡),内容区直接坐灰底,页面白卡浮在灰上 */
/* 主区内容容器:白底承载内容,与透明侧栏(灰底)形成明显区分;
* 圆角 + 阴影让白卡在灰底上浮起,层次清晰 */
.fms-main {
display: flex;
flex-direction: column;
@@ -235,9 +224,13 @@ function onSplitterResize(sizes) {
min-width: 0;
min-height: 0;
overflow: hidden;
background: var(--fms-card);
border-radius: var(--fms-control-radius);
box-shadow: var(--fms-shadow);
}
/* 内容区:透明,灰底由 .fms-layout 提供(页面白卡直接浮在灰上) */
/* 内容区:白卡内滚动区,顶部由 .fms-tabs 的底边线分隔。
* flex column:让页面根可用 flex:1 撑满可视高度(百分比高度链在滚动容器内不可靠) */
.fms-content {
flex: 1;
min-height: 0;
@@ -152,16 +152,12 @@ function toNavItem(node) {
</template>
<style lang="scss" scoped>
/* ---- 侧栏容器:白色圆角卡(带框架阴影,浮在灰底上),内部分区滚动 ---- */
/* ---- 侧栏容器 ---- */
.fms-sidebar-body {
display: flex;
flex-direction: column;
height: 100%;
min-width: 0;
overflow: hidden;
background: var(--fms-card);
border-radius: var(--fms-control-radius);
box-shadow: var(--fms-frame-shadow);
}
/* 团队切换(对齐 SidebarHeader p-2 + TeamSwitcher h-12) */
@@ -65,10 +65,6 @@ onMounted(() => {
onBeforeUnmount(() => {
resizeObserver?.disconnect()
resizeObserver = null
if (scrollStateRaf != null) {
cancelAnimationFrame(scrollStateRaf)
scrollStateRaf = null
}
trackRef.value?.removeEventListener('wheel', handleWheel)
})
@@ -135,33 +131,19 @@ function handleTabAction(action, key) {
}
}
// 溢出/滚动状态:仅在实际变化时更新,并用 rAF 延迟到下一帧提交 ——
// 箭头 v-if 的显示切换会改变轨道宽度,若在 ResizeObserver 回调内同步改布局,
// 会在同一帧内触发新一轮观察,造成「ResizeObserver loop」错误。
let scrollStateRaf = null
function updateScrollState() {
const track = trackRef.value
if (!track) return
const shouldOverflow = track.scrollWidth > track.clientWidth + 1
const left = shouldOverflow ? track.scrollLeft > 1 : false
const right = shouldOverflow
? track.scrollLeft + track.clientWidth < track.scrollWidth - 1
: false
if (
shouldOverflow === overflowed.value &&
left === canScrollLeft.value &&
right === canScrollRight.value
) {
overflowed.value = shouldOverflow
if (!shouldOverflow) {
track.scrollLeft = 0
canScrollLeft.value = false
canScrollRight.value = false
return
}
if (scrollStateRaf != null) return
scrollStateRaf = requestAnimationFrame(() => {
scrollStateRaf = null
if (!shouldOverflow) track.scrollLeft = 0
overflowed.value = shouldOverflow
canScrollLeft.value = left
canScrollRight.value = right
})
canScrollLeft.value = track.scrollLeft > 1
canScrollRight.value = track.scrollLeft + track.clientWidth < track.scrollWidth - 1
}
function scrollTabs(direction) {
@@ -105,6 +105,7 @@ onBeforeUnmount(() => document.removeEventListener('fullscreenchange', syncFulls
>
<PanelLeft />
</Button>
<span class="fms-separator" aria-hidden="true" />
</div>
@@ -203,7 +204,7 @@ onBeforeUnmount(() => document.removeEventListener('fullscreenchange', syncFulls
</template>
<style lang="scss" scoped>
/* ---- 顶栏(已合并页签,白色浮条,带框架阴影) ---- */
/* ---- 顶栏 ---- */
.fms-topbar {
display: flex;
align-items: center;
@@ -211,9 +212,10 @@ onBeforeUnmount(() => document.removeEventListener('fullscreenchange', syncFulls
gap: 8px;
height: 40px;
padding: 0 12px;
/* 顶栏独立成一块:与 .fms-main 同款白底 + 圆角 + 同款投影,与下方白卡并列分层 */
background: var(--fms-card);
border-radius: var(--fms-control-radius);
box-shadow: var(--fms-frame-shadow);
box-shadow: var(--fms-shadow);
}
.fms-topbar-left,
@@ -218,12 +218,12 @@ function onToggle() {
min-height: 28px;
}
/* 激活高亮:主题色浅底 + 主题色文字(白色侧栏上可见) */
/* 激活高亮:主色淡底 + 主色文字(与树选中态一致)。
侧栏为浅灰底时白底+阴影会形成突兀的白块,改用主色淡底融入浅灰侧栏 */
.fms-nav-link.is-active {
background: color-mix(in srgb, var(--fms-primary) 10%, var(--fms-card));
background: color-mix(in srgb, var(--fms-primary) 10%, transparent);
color: var(--fms-primary);
font-weight: 500;
box-shadow: none;
}
/* ---- 折叠态:仅图标,居中展示(对齐 size-8 icon 模式) ---- */