Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: layout and Page style adjustment #5033

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions docs/src/components/layout-ui/page.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ outline: deep

### Props

| 属性名 | 描述 | 类型 | 默认值 |
| --- | --- | --- | --- |
| title | 页面标题 | `string\|slot` | - |
| description | 页面描述(标题下的内容) | `string\|slot` | - |
| contentClass | 内容区域的class | `string` | - |
| headerClass | 头部区域的class | `string` | - |
| footerClass | 底部区域的class | `string` | - |
| autoContentHeight | 自动调整内容区域的高度 | `boolean` | `false` |
| fixedHeader | 固定头部在页面内容区域顶部,在滚动时保持可见 | `boolean` | `false` |
| 属性名 | 描述 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| title | 页面标题 | `string\|slot` | - | - |
| description | 页面描述(标题下的内容) | `string\|slot` | - | - |
| contentClass | 内容区域的class | `string` | - | - |
| headerClass | 头部区域的class | `string` | - | `v5.5.0` |
| footerClass | 底部区域的class | `string` | - | `v5.5.0` |
| autoContentHeight | 自动调整内容区域的高度 | `boolean` | `false` | - |
| fixedHeader | 固定头部在页面内容区域顶部,在滚动时保持可见 | `boolean` | `false` | `v5.5.0` |

::: tip 注意

如果`title`、`description`、`extra`三者均未提供有效内容(通过`props`或者`slots`均可),则页面头部区域不会渲染。
如果`title`、`description`、`extra`三者均未提供有效内容(通过`props`或者`slots`均可),则页面头部区域不会渲染。另外,`fixedHeader`属性目前仅在顶栏模式(`header.mode`)为`固定`(`fixed`)时有效。

:::

Expand Down
2 changes: 1 addition & 1 deletion packages/@core/ui-kit/layout-ui/src/vben-layout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ function handleHeaderToggle() {

<div
ref="contentRef"
class="flex flex-1 flex-col transition-all duration-300 ease-in"
class="flex flex-1 flex-col overflow-hidden transition-all duration-300 ease-in"
>
<div
:class="[
Expand Down
116 changes: 78 additions & 38 deletions packages/effects/common-ui/src/components/page/page.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
<script setup lang="ts">
import {
computed,
nextTick,
onMounted,
ref,
type StyleValue,
useTemplateRef,
} from 'vue';
import { computed, onMounted, ref, type StyleValue, useTemplateRef } from 'vue';

import { preferences } from '@vben-core/preferences';
import {
CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT,
CSS_VARIABLE_LAYOUT_CONTENT_WIDTH,
CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT,
CSS_VARIABLE_LAYOUT_HEADER_HEIGHT,
} from '@vben-core/shared/constants';
import { cn } from '@vben-core/shared/utils';

import { useElementSize } from '@vueuse/core';

interface Props {
title?: string;
description?: string;
Expand All @@ -37,43 +38,79 @@ const {
fixedHeader = false,
} = defineProps<Props>();

const headerHeight = ref(0);
const footerHeight = ref(0);
const shouldAutoHeight = ref(false);

const headerRef = useTemplateRef<HTMLDivElement>('headerRef');
const footerRef = useTemplateRef<HTMLDivElement>('footerRef');

const isHeaderFixed = computed(() => {
return preferences.header.mode === 'fixed' && fixedHeader;
});
const { height: headerHeight } = useElementSize(
headerRef,
{
height: 0,
width: 0,
},
{ box: 'border-box' },
);
const { height: footerHeight } = useElementSize(
footerRef,
{
height: 0,
width: 0,
},
{ box: 'border-box' },
);
mynetfan marked this conversation as resolved.
Show resolved Hide resolved

const headerStyle = computed<StyleValue>(() => {
return fixedHeader
return isHeaderFixed.value
? {
position: 'sticky',
position: 'fixed',
zIndex: 200,
width: `var(${CSS_VARIABLE_LAYOUT_CONTENT_WIDTH})`,
top:
preferences.header.mode === 'fixed' ? 'var(--vben-header-height)' : 0,
preferences.header.mode === 'fixed'
? `var(${CSS_VARIABLE_LAYOUT_HEADER_HEIGHT})`
: 0,
mynetfan marked this conversation as resolved.
Show resolved Hide resolved
}
: undefined;
});

const footerStyle = computed<StyleValue>(() => {
return {
zIndex: 201,
bottom:
preferences.footer.enable && preferences.footer.fixed
? `var(${CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT})`
: 0,
width: `var(${CSS_VARIABLE_LAYOUT_CONTENT_WIDTH})`,
};
});

const contentStyle = computed(() => {
const style: StyleValue = {};
if (headerHeight.value > 0 && isHeaderFixed.value) {
style.marginTop = `${headerHeight.value}px`;
}
if (footerHeight.value > 0) {
style.marginBottom = `${footerHeight.value}px`;
}
if (autoContentHeight) {
return {
height: shouldAutoHeight.value
? `calc(var(--vben-content-height) - ${headerHeight.value}px - ${footerHeight.value}px)`
: '0',
// 'overflow-y': shouldAutoHeight.value?'auto':'unset',
};
style.height = shouldAutoHeight.value
? `calc(var(${CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT}) - ${headerHeight.value}px - ${footerHeight.value}px)`
: '0';
}
return {};
return style;
});

async function calcContentHeight() {
if (!autoContentHeight) {
return;
}
await nextTick();
headerHeight.value = headerRef.value?.offsetHeight || 0;
footerHeight.value = footerRef.value?.offsetHeight || 0;
// await nextTick();
// headerHeight.value = headerRef.value?.offsetHeight || 0;
// footerHeight.value = footerRef.value?.offsetHeight || 0;
setTimeout(() => {
shouldAutoHeight.value = true;
}, 30);
Expand All @@ -97,7 +134,7 @@ onMounted(() => {
ref="headerRef"
:class="
cn(
'bg-card relative px-6 py-4',
'bg-card relative flex gap-2 px-6 py-4',
headerClass,
fixedHeader
? 'border-border border-b transition-all duration-200'
Expand All @@ -106,19 +143,21 @@ onMounted(() => {
"
:style="headerStyle"
>
<slot name="title">
<div v-if="title" class="mb-2 flex text-lg font-semibold">
{{ title }}
</div>
</slot>

<slot name="description">
<p v-if="description" class="text-muted-foreground">
{{ description }}
</p>
</slot>

<div v-if="$slots.extra" class="absolute bottom-4 right-4">
<div class="flex-auto">
<slot name="title">
<div v-if="title" class="mb-2 flex text-lg font-semibold">
{{ title }}
</div>
</slot>

<slot name="description">
<p v-if="description" class="text-muted-foreground">
{{ description }}
</p>
</slot>
</div>

<div v-if="$slots.extra" class="mb-2 self-end">
<slot name="extra"></slot>
</div>
</div>
Expand All @@ -133,9 +172,10 @@ onMounted(() => {
:class="
cn(
footerClass,
'bg-card align-center absolute bottom-0 left-0 right-0 flex px-6 py-4',
'bg-card align-center border-border fixed flex border-b border-t px-6 py-4 transition-all duration-200',
)
"
:style="footerStyle"
>
<slot name="footer"></slot>
</div>
Expand Down
1 change: 1 addition & 0 deletions playground/src/views/examples/vxe-table/basic.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ function changeLoading() {
<template>
<Page
description="表格组件常用于快速开发数据展示与交互界面,示例数据为静态数据。该组件是对vxe-table进行简单的二次封装,大部分属性与方法与vxe-table保持一致。"
fixed-header
title="表格基础示例"
>
<template #extra>
Expand Down
Loading