Preview Updated 2026-05-10

AppShell

A header + sidebar + main + aside + footer CSS Grid layout — a recommended starting point for full-app scaffolding.

Basic usage

AppShell fixes the most common layout regions: a sticky header, a left sidebar, an optional right aside, the main area, and a footer. Each region is a named slot / prop — leaving it empty omits the region.

The sidebar width is controlled via sidebarWidth (number, px); sidebarCollapsed=true shrinks the sidebar to zero width while keeping its DOM, which is convenient for responsive toggling.

My App[email protected]

主区域

点击左上角按钮可以收起 / 展开侧栏。

© ChuFix · v0.0.1
<script setup lang="ts">
import { ref } from 'vue';
import { CfAppShell, CfButton } from '@chufix-design/vue';

const collapsed = ref(false);
</script>

<template>
<CfAppShell :sidebar-collapsed="collapsed" :sidebar-width="180">
  <template #header>
    <CfButton size="sm" variant="tertiary" @click="collapsed = !collapsed">
      {{ collapsed ? 'Expand sidebar' : 'Collapse sidebar' }}
    </CfButton>
    <strong>My App</strong>
  </template>
  <template #sidebar>
    <nav>Navigation list</nav>
  </template>
  <template #footer>© ChuFix</template>
  <div>Main content</div>
</CfAppShell>
</template>
import { useState } from 'react';
import { CfAppShell, CfButton } from '@chufix-design/react';

export default function Demo() {
const [collapsed, setCollapsed] = useState(false);
return (
  <CfAppShell
    sidebarCollapsed={collapsed}
    sidebarWidth={180}
    header={
      <>
        <CfButton size="sm" variant="tertiary" onClick={() => setCollapsed((v) => !v)}>
          {collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
        </CfButton>
        <strong>My App</strong>
      </>
    }
    sidebar={<nav>Navigation list</nav>}
    footer={<>© ChuFix</>}
  >
    <div>Main content</div>
  </CfAppShell>
);
}

Layout regions

┌──────────────────────────────────────────┐
│             header (sticky)              │
├────────┬──────────────────┬──────────────┤
│        │                  │              │
│ side-  │      main        │   aside      │
│ bar    │                  │  (right col) │
│        │                  │              │
├────────┴──────────────────┴──────────────┤
│                  footer                  │
└──────────────────────────────────────────┘
  • header defaults to position: sticky; top: 0 and stays pinned while the main area scrolls
  • sidebar / aside / main each have their own overflow-y: auto and scroll independently; all use overscroll-behavior: contain to prevent scroll chaining
  • The whole shell uses display: grid, with regions defined by grid-template-areas

With a right aside

The aside slot enables the rightmost column — useful for detail panels, outlines, or tip rails. asideWidth controls its width.

顶栏
主内容区,左右两侧栏 + 顶底栏的完整脚手架。
底栏
<CfAppShell :sidebar-width="160" :aside-width="200">
<template #header>Header</template>
<template #sidebar>Left navigation</template>
<template #aside>Right aside</template>
<template #footer>Footer</template>
<div>Main content</div>
</CfAppShell>
<CfAppShell
sidebarWidth={160}
asideWidth={200}
header={<>Header</>}
sidebar={<>Left navigation</>}
aside={<>Right aside</>}
footer={<>Footer</>}
>
<div>Main content</div>
</CfAppShell>

Three density variants

variant controls the overall font size / spacing tier — default / condensed (compact admin) / spacious (landing pages or large screens).

variant = condensed
condensed 顶栏
紧凑型 — 整体字号小一档
variant = spacious
spacious 顶栏
宽松型 — 字号 / 内距大一档
<CfAppShell variant="condensed">…</CfAppShell>
<CfAppShell variant="spacious">…</CfAppShell>
<CfAppShell variant="condensed">…</CfAppShell>
<CfAppShell variant="spacious">…</CfAppShell>

API

PropTypeDefaultDescription
variant'default' | 'condensed' | 'spacious''default'Overall font size tier
sidebarWidthnumber240Sidebar width (px)
headerHeightnumberautoFixed header height (px); auto-fits content when omitted
borderedbooleantrueWhether the sidebar shows a right border
sidebarCollapsedbooleanfalseWhether to collapse the sidebar (visual width 0)

Vue slots: header / sidebar / aside / footer / default (main). React accepts the same names as ReactNode props; main content goes through children.

反馈与讨论

AppShell · Discussion

0
0 / 600
一键发送
正在加载评论...