App Shell
Full-page layout scaffold that composes a TopBar, Sidebar, and scrollable content area into a cohesive application frame. Handles responsive collapse, sidebar toggling, and optional table-of-contents rail out of the box.
<arc-app-shell> Overview
>
AppShell is the outermost structural component for any ARC UI application. It establishes the canonical three-zone layout — a fixed top bar, a collapsible sidebar, and a flexible main content area — so that every page in your app shares a consistent chrome without duplicating layout logic.
The component manages responsive behavior automatically. On screens narrower than 768 px the sidebar collapses out of view and can be toggled back with the `sidebar-open` attribute, making it suitable for both desktop dashboards and mobile-first admin panels. A fourth optional slot, `toc`, provides a right-hand rail for table-of-contents or contextual widgets; it hides below 1280 px to keep the content area readable.
Because AppShell is slot-based, it composes freely with other ARC UI primitives. Drop an `arc-top-bar` into the `topbar` slot, an `arc-sidebar` (or any nav markup) into `sidebar`, and your page content into the default slot. The shell handles all the flex math, scroll containment, and z-index layering so you can focus on what goes inside each zone rather than how the zones relate to each other.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
- Do not nest one AppShell inside another — it is designed as a singleton page frame
- Do not put scrollable content directly in the sidebar slot without its own overflow handling
- Do not rely on the toc slot for critical navigation — it hides on narrower viewports
- Do not override min-height: 100vh on the host unless you are embedding a preview or iframe
- Do not 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: `
<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>
<ng-content />
</main>
</arc-app-shell>
`,
})
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">
AppShell
</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">
AppShell
</div>
<div class="shell__toc" style="flex-shrink: 0; width: 220px">
<!-- optional table-of-contents -->
</div>
</div>
</div>
</div>
</div> API
-
sidebar-openbooleanfalse - 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.
-
breakpointnumber - Viewport width in pixels at which the layout switches between mobile and desktop modes.
Events
-
arc-sidebar-toggledetail: { value: boolean } - Fired when the shell itself opens or closes the mobile sidebar — on a backdrop click, on Escape, or on navigation. Listened to by arc-top-bar so its hamburger stays in step. Not fired for a toggle the shell merely received, so the two cannot echo each other.
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.