Blocks
Layout
Dashboard shell with optional nav, left, and right rails, toolbar, main column, and footer.
Usage
Use MeLayout as the root layout: fill only the slots you need (header, nav, left and optional right rails, toolbar, analytics, main content, footer). Below lg, rails open as slideovers unless you pass inlineSidebarsOnMobile.
Loading preview...
<template>
<div class="flex h-[28rem] w-full max-w-full flex-col gap-2 text-sm">
<fieldset class="shrink-0 rounded-md border border-default bg-muted/30 p-3">
<legend class="px-1 text-xs font-medium text-muted">Show slots</legend>
<div class="mt-1 flex flex-wrap gap-x-4 gap-y-2">
<label class="inline-flex cursor-pointer items-center gap-2">
<input v-model="showHeader" type="checkbox" class="rounded border-default">
Header
</label>
<label class="inline-flex cursor-pointer items-center gap-2">
<input v-model="showNav" type="checkbox" class="rounded border-default">
Nav
</label>
<label class="inline-flex cursor-pointer items-center gap-2">
<input v-model="showLeft" type="checkbox" class="rounded border-default">
Left
</label>
<label class="inline-flex cursor-pointer items-center gap-2">
<input v-model="showRight" type="checkbox" class="rounded border-default">
Right
</label>
<label class="inline-flex cursor-pointer items-center gap-2">
<input v-model="showToolbar" type="checkbox" class="rounded border-default">
Toolbar
</label>
<label class="inline-flex cursor-pointer items-center gap-2">
<input v-model="showAnalytics" type="checkbox" class="rounded border-default">
Analytics
</label>
<label class="inline-flex cursor-pointer items-center gap-2">
<input v-model="showFooter" type="checkbox" class="rounded border-default">
Footer
</label>
</div>
</fieldset>
<div class="min-h-0 flex-1 overflow-hidden rounded-md border border-default">
<MeLayout class="!h-full min-h-0 w-full">
<template v-if="showHeader" #header>
<div class="flex h-12 w-full shrink-0 items-center border-b border-default bg-default px-4 font-medium">
My App
</div>
</template>
<template v-if="showNav" #nav-area>
<div class="flex h-full flex-col items-center justify-center gap-2 p-2 text-xs text-muted">
Nav
</div>
</template>
<template v-if="showLeft" #left-area>
<aside class="p-3">Left</aside>
</template>
<template v-if="showToolbar" #toolbar>
<div class="px-2 py-1.5 text-muted">Toolbar</div>
</template>
<template v-if="showAnalytics" #analytics>
<div class="p-4">Analytics</div>
</template>
<template #default>
<div class="p-4">Main content</div>
</template>
<template v-if="showRight" #right-area>
<aside class="p-3">Right</aside>
</template>
<template v-if="showFooter" #footer>
<div class="px-4 py-2 text-xs text-muted">Footer</div>
</template>
</MeLayout>
</div>
</div>
</template>
<script setup>
const showHeader = ref(true)
const showNav = ref(false)
const showLeft = ref(true)
const showRight = ref(false)
const showAnalytics = ref(false)
const showToolbar = ref(true)
const showFooter = ref(false)
</script>
Rail sizing
Nav rail width is fixed at 5.5rem. Set unit and optional leftArea / rightArea for the resizable sidebars. The default unit is px; use unit="%" when your numbers are percentages (as in the example).
App
Content
<template>
<MeLayout
unit="%"
:left-area="{
minSize: 10,
defaultSize: 18,
maxSize: 28,
resizable: true,
collapsible: true
}"
:right-area="{
minSize: 8,
defaultSize: 12,
maxSize: 20,
resizable: false,
collapsible: false
}"
>
<template #header><div class="flex h-12 w-full items-center border-b border-default px-4 text-sm font-medium">App</div></template>
<template #nav-area><div class="flex h-full items-center justify-center p-2 text-xs text-muted">Nav</div></template>
<template #left-area><div class="p-3 text-sm">Left</div></template>
<template #default><div class="p-4 text-sm">Content</div></template>
<template #right-area><div class="p-3 text-sm">Right</div></template>
</MeLayout>
</template>
API
Props
| Prop | Default | Type |
|---|---|---|
unit | 'px' | '%' | 'px' | 'rem' Unit for left and right sidebar sizes. |
inlineSidebarsOnMobile | [] | LayoutInlineSidebarKey[] Rails that stay in the row under lg instead of slideover. |
storage | 'cookie' | 'cookie' | 'local' Where sizes are stored. |
storageKey | 'layout' | string Storage key for this layout group. |
leftArea | { resizable: true, collapsible: true } | LayoutLeftAreaConfig minSize, defaultSize, maxSize, resizable, collapsible. Defaults: px 200/240/400, % 10/15/25, rem 12/15/25. |
rightArea | { resizable: true, collapsible: true } | LayoutRightAreaConfig Same as leftArea. Defaults: px 260/358/640, % 8/12/20, rem 16/22.5/40. |
Slots
| Slot | Type |
|---|---|
header | void |
nav-area | LayoutMobileSidebarSlotProps |
nav-area-header | LayoutSidebarRailHeaderSlotProps |
left-area | LayoutMobileSidebarSlotProps |
left-area-header | LayoutSidebarRailHeaderSlotProps |
toolbar | LayoutMobileToolbarSlotProps |
analytics | void |
default | void |
right-area | LayoutMobileSidebarSlotProps |
right-area-header | LayoutSidebarRailHeaderSlotProps |
footer | void |
Rail slot bodies use horizontal clipping; wrap wide content in overflow-x-auto min-w-0.