侧栏收拢时导航按钮跟着缩窄;配置区高度折叠动画;侧栏不再牵动页面内容
导航按钮宽度写死 159px 而不是 100%,百分比到像素之间没法插值,收拢时 按钮平滑缩成 36px 的方形贴住图标,高亮块不再被裁切出血。配置表单和 链式代理段的出现消失改成高度折叠(量出目标高度做插值,margin 换成 padding 否则那一截在动画之外瞬跳)。路由页「新增」按钮的文字不再跟着 侧栏密度隐藏:侧栏收拢是侧栏自己的事。
This commit is contained in:
@@ -160,6 +160,39 @@ function lockHeight() {
|
||||
el.style.overflow = 'hidden'
|
||||
}
|
||||
|
||||
/**
|
||||
* v-if 内容的展开收起动画:高度在 0 和实际值之间过渡,结束后清掉内联样式。
|
||||
* 给配置表单和链式代理段用。auto 高度不可插值,只能量出来做。
|
||||
*/
|
||||
function foldEnter(element: Element, done: () => void) {
|
||||
const el = element as HTMLElement
|
||||
el.style.height = '0'
|
||||
el.style.overflow = 'hidden'
|
||||
void el.offsetHeight
|
||||
el.style.transition = 'height 0.15s ease'
|
||||
el.style.height = `${String(el.scrollHeight)}px`
|
||||
el.addEventListener(
|
||||
'transitionend',
|
||||
() => {
|
||||
el.style.transition = ''
|
||||
el.style.height = ''
|
||||
el.style.overflow = ''
|
||||
done()
|
||||
},
|
||||
{ once: true },
|
||||
)
|
||||
}
|
||||
|
||||
function foldLeave(element: Element, done: () => void) {
|
||||
const el = element as HTMLElement
|
||||
el.style.height = `${String(el.offsetHeight)}px`
|
||||
el.style.overflow = 'hidden'
|
||||
void el.offsetHeight
|
||||
el.style.transition = 'height 0.15s ease'
|
||||
el.style.height = '0'
|
||||
el.addEventListener('transitionend', done, { once: true })
|
||||
}
|
||||
|
||||
function settleHeight() {
|
||||
const el = rootEl.value
|
||||
if (!el || !el.style.height) return
|
||||
@@ -507,6 +540,7 @@ const complete = computed(
|
||||
</section>
|
||||
|
||||
<!-- 跟着表单里的开关走:拨开立刻出现,拨掉(哪怕还没保存)立刻消失 -->
|
||||
<Transition name="fold" @enter="foldEnter" @leave="foldLeave">
|
||||
<section v-if="form.chain" class="block">
|
||||
<h3>
|
||||
链式代理
|
||||
@@ -546,6 +580,7 @@ const complete = computed(
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</Transition>
|
||||
|
||||
<!-- 共用的组只能换选中,改不了它的成员来源:那是别人的组 -->
|
||||
<section v-if="panel.shared && !locked" class="block">
|
||||
@@ -560,6 +595,7 @@ const complete = computed(
|
||||
<IconRight :class="['chev', open && 'is-open']" />
|
||||
</button>
|
||||
|
||||
<Transition name="fold" @enter="foldEnter" @leave="foldLeave">
|
||||
<div v-if="open" class="form">
|
||||
<h4>代理</h4>
|
||||
|
||||
@@ -631,6 +667,7 @@ const complete = computed(
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</section>
|
||||
</template>
|
||||
</div>
|
||||
@@ -899,12 +936,13 @@ h3 {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
/* 表单不套盒子,靠小标题和一条分割线分段(设计基调第 2 条:不要卡片套卡片) */
|
||||
/* 表单不套盒子,靠小标题和一条分割线分段(设计基调第 2 条:不要卡片套卡片)。
|
||||
上方留白用 padding 而不是 margin:margin 在高度折叠动画之外,会瞬跳 */
|
||||
.form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--s-3);
|
||||
margin-top: var(--s-4);
|
||||
padding-top: var(--s-4);
|
||||
}
|
||||
|
||||
.form h4 {
|
||||
|
||||
@@ -28,7 +28,6 @@ import type { ListenerFields } from '../api'
|
||||
import type { GroupView } from '../runtime'
|
||||
import { optimisticSelect, providerLines, reloadRuntime, runtime } from '../runtime'
|
||||
import { useDelayTest } from '../delay-test'
|
||||
import { density } from '../prefs'
|
||||
import ConfirmDialog from '../components/ConfirmDialog.vue'
|
||||
import InboundList from '../components/InboundList.vue'
|
||||
import InboundDetail from './InboundDetail.vue'
|
||||
@@ -258,9 +257,10 @@ async function removeConfirmed() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 侧栏收拢是侧栏自己的事,页面内容不跟着变形 -->
|
||||
<button class="add" type="button" :disabled="saving" @click="openAdd">
|
||||
<IconAdd />
|
||||
<span v-if="density === 'full'">新增</span>
|
||||
<span>新增</span>
|
||||
</button>
|
||||
</header>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user