<arc-app-shell> Overview
Guidelines
When to use
- Use one AppShell as the root layout wrapper for each page or route
- Place an arc-top-bar in the "topbar" slot for a consistent fixed header
- Provide a sidebar toggle button in the top bar that sets sidebar-open on mobile
- Use the "toc" slot for table-of-contents navigation on documentation pages
- Combine with Container or Section components inside the default slot for consistent content widths
When not to use
- Nest one AppShell inside another — it is designed as a singleton page frame
- Put scrollable content directly in the sidebar slot without its own overflow handling
- Rely on the toc slot for critical navigation — it hides on narrower viewports
- Override min-height: 100vh on the host unless you are embedding a preview or iframe
- Use AppShell for simple marketing pages that do not need a persistent sidebar or top bar
Features
- Three-zone layout: fixed top bar, collapsible sidebar, scrollable main content
- Optional fourth "toc" slot for a right-hand table-of-contents rail
- Responsive sidebar collapse at 768 px with toggle via sidebar-open attribute
- Table-of-contents rail auto-hides below 1280 px
- Slot-based composition works with any TopBar, Sidebar, or custom markup
- Full-viewport min-height ensures the shell always fills the screen
- CSS custom property integration for consistent spacing and color tokens
- Exposed CSS parts (shell, body, sidebar, main, content, toc) for deep style overrides
Preview
Usage
Layout and styling work without JavaScript via the HTML/CSS versions. Interactive features like events and state management require the Web Component or a framework wrapper.
<script type="module" src="@arclux/arc-ui"></script>
<arc-app-shell>
<arc-top-bar slot="topbar" heading="Dashboard"></arc-top-bar>
<nav slot="sidebar" style="width: 200px; padding: 16px;">
<a href="/overview">Overview</a>
<a href="/analytics">Analytics</a>
<a href="/settings">Settings</a>
</nav>
<main>
<h1>Welcome back</h1>
<p>Here is what happened while you were away.</p>
</main>
</arc-app-shell> import { AppShell, TopBar } from '@arclux/arc-ui-react';
export function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
<AppShell>
<TopBar slot="topbar" heading="Dashboard" />
<nav slot="sidebar" style={{ width: 200, padding: 16 }}>
<a href="/overview">Overview</a>
<a href="/analytics">Analytics</a>
<a href="/settings">Settings</a>
</nav>
<main>{children}</main>
</AppShell>
);
} <script setup>
import { AppShell, TopBar } from '@arclux/arc-ui-vue';
</script>
<template>
<AppShell>
<TopBar slot="topbar" heading="Dashboard" />
<nav slot="sidebar" style="width: 200px; padding: 16px;">
<a href="/overview">Overview</a>
<a href="/analytics">Analytics</a>
<a href="/settings">Settings</a>
</nav>
<main>
<slot />
</main>
</AppShell>
</template> <script>
import { AppShell, TopBar } from '@arclux/arc-ui-svelte';
</script>
<AppShell>
<TopBar slot="topbar" heading="Dashboard" />
<nav slot="sidebar" style="width: 200px; padding: 16px;">
<a href="/overview">Overview</a>
<a href="/analytics">Analytics</a>
<a href="/settings">Settings</a>
</nav>
<main>
<slot />
</main>
</AppShell> import { Component } from '@angular/core';
import { AppShell, TopBar } from '@arclux/arc-ui-angular';
@Component({
imports: [AppShell, TopBar],
template: `
<AppShell>
<TopBar slot="topbar" heading="Dashboard"></TopBar>
<nav slot="sidebar" style="width: 200px; padding: 16px;">
<a href="/overview">Overview</a>
<a href="/analytics">Analytics</a>
<a href="/settings">Settings</a>
</nav>
<main>
<ng-content />
</main>
</AppShell>
`,
})
export class DashboardLayoutComponent {} import { AppShell, TopBar } from '@arclux/arc-ui-solid';
import type { ParentProps } from 'solid-js';
export function DashboardLayout(props: ParentProps) {
return (
<AppShell>
<TopBar slot="topbar" heading="Dashboard" />
<nav slot="sidebar" style={{ width: '200px', padding: '16px' }}>
<a href="/overview">Overview</a>
<a href="/analytics">Analytics</a>
<a href="/settings">Settings</a>
</nav>
<main>{props.children}</main>
</AppShell>
);
} import { AppShell, TopBar } from '@arclux/arc-ui-preact';
import type { ComponentChildren } from 'preact';
export function DashboardLayout({ children }: { children: ComponentChildren }) {
return (
<AppShell>
<TopBar slot="topbar" heading="Dashboard" />
<nav slot="sidebar" style={{ width: 200, padding: 16 }}>
<a href="/overview">Overview</a>
<a href="/analytics">Analytics</a>
<a href="/settings">Settings</a>
</nav>
<main>{children}</main>
</AppShell>
);
} <!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-app-shell — requires app-shell.css + base.css (or arc-ui.css) -->
<div class="arc-app-shell">
<div class="shell">
<div class="shell__body">
<div class="shell__sidebar">
<!-- sidebar nav goes here -->
</div>
<div class="shell__main">
<div class="shell__content">
App Shell
</div>
<div class="shell__toc">
<!-- optional table-of-contents -->
</div>
</div>
</div>
</div>
</div> <!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-app-shell — self-contained, no external CSS needed -->
<style>
@media (max-width: 1280px) {
.arc-app-shell .shell__toc { display: none; }
}
@media (max-width: 768px) {
.arc-app-shell .shell__sidebar { display: none; }
}
@media (max-width: 768px) {
.arc-app-shell([sidebar-open]) .shell__sidebar { display: block; }
}
</style>
<div class="arc-app-shell" style="display: block; min-height: 100vh; background: rgb(3, 3, 7); color: rgb(232, 232, 236)">
<div class="shell" style="display: flex; flex-direction: column; min-height: 100vh">
<div style="display: flex; flex: 1; padding-top: 64px">
<div class="shell__sidebar" style="flex-shrink: 0">
<!-- sidebar nav goes here -->
</div>
<div style="flex: 1; min-width: 0; display: flex">
<div style="flex: 1; min-width: 0; padding: 40px 40px; max-width: 860px">
App Shell
</div>
<div class="shell__toc" style="flex-shrink: 0; width: 220px">
<!-- optional table-of-contents -->
</div>
</div>
</div>
</div>
</div> API
| Prop | Type | Default | Description |
|---|---|---|---|
sidebar-open | boolean | false | Controls whether the sidebar is visible on mobile viewports (below 768 px). On desktop the sidebar is always shown regardless of this attribute. Toggle it from a hamburger button in your TopBar to give mobile users access to navigation. |
breakpoint | number | 768 | Viewport width in pixels at which the layout switches between mobile and desktop modes. |
See Also
- Page Layout Page structure primitive that arranges content into sidebar-left, sidebar-right, centered, or wide layouts using CSS Grid. Handles responsive collapse, configurable gap and max-width, and exposes named slots for sidebar, main, and aside regions.
- Sidebar Collapsible navigation sidebar with grouped sections, heading labels, and active link highlighting. Ideal for documentation sites, admin panels, and any layout that needs persistent vertical navigation.
- Top Bar Fixed header bar that anchors every page with a brand slot on the left, an optional center navigation area, and a right-aligned actions region for user controls, search, and settings.
- Footer Page footer with branding, link columns, and legal text. Provides a structured layout with slots for a logo, navigational link groups, social icons, and copyright information.
- Auth Shell Authentication page layout with centered and split variants for sign-in, sign-up, password-reset, and other credential flows. Provides logo, form card, footer, and optional aside slots out of the box.